s25 = {}; s25.meta = {};
//s25.metas = "" + <r><![CDATA[
// ==UserScript==
// @name           Salon25
s25.meta.name =   "Salon25";
// @namespace      http://juljas.net/
// @description    Dodatkowe funkcje i poprawki do Salonu24
// @version        1.0.39
s25.meta.version ="1.0.39";
// @copyright      (C) 2008-2011, greasemonkey (greasemonkey.salon24.pl) & Jan Słupski (follow.salon24.pl)
// @icon           http://juljas.net/s24/faq/salon25/salon25.png
// @include        http://*.salon24.pl/*
// @include        http://*.tek24.pl/*
// @include        http://*.sportifo24.pl/*
// @exclude        http://*http://*.salon24.pl/*
//]]></r>.toString(); //this was beautiful all-in-one but does not work on Google Chrome


/* http://code.google.com/p/salon25/w/edit/Funkcje
#summary Funkcje skryptu Salon25
#labels Featured
= Funkcje działające =
  * górny (czarny) pasek menu
    * link 'obserwowane'
    * informacja o liczbie notek z nieprzeczytanymi komentarzami w obserwowanych (+podświetlenie)
    * kliknięcie w liczbę nieprzeczytanych notek przenosi do pierwszego nieczytanego komentarza pierwszej notki
    * zarządzanie wyglądem górnego menu (ukrywanie pozycji menu, skracanie nazw linków)
    * informacja o nowej wiadomości w skrzynce pocztowej (automatyczna aktualizacja)
    * automatyczna aktualizacja informacji o poczcie i obserwowanych
  * strona główna
    * przywrócenie użytkownikowi decyzji czy wchodzi do lubczasopisma czy do blogu autora
    * "znormalizowany" wygląd notek lubczasopismowych na SG (nick pod notką a nie w tytule)
    * eksperymentalne: aktywne dyskusje na sg
    * ukryj "chmurkę" Facebooka
  * notki
    * edycja notki w czystym HTML - przycisk w edytorze WYSIWYG: "Żródło dokumentu"
    * przycisk 'rozwiń wszystkie komentarze' 
    * kolorowanie 'zafiltrowanych' komentarzy gdy sa rozwinięte (opcja)
    * opcja automatycznie rozwijaj wszystkie komentarze
    * eksperymentalne: dowolne sortowanie bloków w prawej kolumnie bloga (opcja)
  * komentarze
    * podgląd wpisywanego komentarza (przed zapisaniem)
    * przycisk 'cytuj zaznaczenie' przy edycji komentarza
    * przycisk 'cytuj komentarz' przy edycji odpowiedzi na komentarz
    * naciśnięcie 'Skomentuj' notkę wstawia '@autor' do tytułu komentarza
    * szablon komentarza
  * blokowanie trolli
    * dostęp do opcji 'zablokuj' autora komentarza na każdym blogu
    * dostęp do opcji 'zablokuj' autora bloga (przycisk w jego profilu)
  * wewnętrzna poczta
    * 'wyślij wiadomość' do autora komentarza - ikona przy każdym komentarzu
    * 'wyślij wiadomość' w profilu każdego bloga
  * obserwowane
    * kliknięcie w liczbę nowych komentarzy na liście obserwowanych -> skok do pierwszego nieczytanego komentarza
    * sortuj obserwowane również po dacie (tylko przy domyślnym sortowaniu po liczbie komentarzy)
  * inne
    * logowanie permanentne - a nie reset logowania po każdym wyjściu z przeglądarki, jako opcja - checkboxem (zmiana cookie z sesyjnego na expire in a week?)
    * na stronie głównej bloga (np. http://follow.salon24.pl/) tytuł notki jest permalinkiem do niej (np. http://follow.salon24.pl/240256,wiecej-zdjec-z-urodzin)
    * link w notce w lubczasopiśmie do tejże notki na blogu autora
    * informacje o nowych wersjach skryptu (+link do instalacji i changeloga)
    * informacja i możliwość przełączania filtrów
    * automatyczne odblokowywanie filtrów
    * menu konfiguracyjne
    * mniejsza czcionka w 'aktywne dyskuje'
    * obsługa Google Chrome (część funkcji)

= Błędy w powyższych funkcjach =
  * kontrola działania skryptu dla niezalogowanych
  * podgląd komentarza nie filtruje tego co filtruje Salon (np. `<script>`, `<object>`, itp.). Warto by było choć częściowo uzupełnić
  * powolne działanie na stronie z dużą ilością komentarzy (np. http://mediaobywatelskie2.salon24.pl/141325,znosimy-wymog-akceptacji-nosg-ale)
  * nie działa: wygodniejsza obsługa 'dodaj do obserwowanych' w notce (bez okienka dialogowego, bez przeładowywania strony)
  * Nie działa link "Zaloguj" gdy menu konfiguracyjne wyświetlone jest dla niezalogowanego użytkownika

= Planowane funkcje =
  * rozbudowa menu konfiguracyjnego (wedle zapotrzebowania)

= Pomysły na dalsze funkcje =
  * formatowanie cytowania (łamanie wierszy + `>` na początku linii)
  * podgląd profilu (w trakcie edycji)
  * hover na obserwowanych pokazuje ile i gdzie nowych odpowiedzi (tylko miejsca mało), chyba że jakieś okienko (+ linki)
  * logowanie zawsze z domeny salon24.pl (a nie domen poszczególnych blogów) bo menadżer haseł głupieje i nie wpisuje zapamiętanego hasła (iframe?)
  * funkcje z Saluuuunu 1.0? (punktowanie/chowanie trolli, ...)
  * kompatybilność z Operą, Safari (jest częściowa)
  * łatwo HTML do komentarzy (w szczególności: linki, obrazki, podstawowe formatowanie)

= Funkcje już w standardzie Salonu24 =
  * edycja komentarza
    * pole odpowiedzi pod komentarzem na który odpowiadam
    * nie dopisuje '#commentadd' do adresu URL po dodaniu komentarza
  * kasowanie komentarzy
    * opcja 'skasuj' do moich komentarzy
    * opcja 'skasuj' do komentarzy na moim blogu
  * obserwowane
    * kasowanie z listy obserwowanych wielu notek na raz
  * inne
    * poprawia 'link do komentarza' (right-mouse-click -> Copy Link Location)
    * przyciski 'nowa notka', 'edytuj notkę' na własnym blogu
    * podgląd notki (w trakcie edycji)
    * jednoetapowe wklejanie zdjęcia z dysku?!

_(w komentarzach poniżej możesz dopisać własne propozycje)_
<wiki:comment>Funkcje END</wiki:comment>
*/
/*
TODO internal

TIPS
  * zamiana id -> nick (wyślij prywatną wiadomość)
  * zamiana nick -> id (blog, komentarz -> zablokuj...)
  * z powodu specyficznej(!) implementacji bezpieczeństwa większość stron z
    http://admin.salon24.pl/ ładuje się tylko jeśli Referer: jest pusty 
    lub ustawiony na: http://admin.salon24.pl/*
  * W związku z powyższym strony administracyjne są ładowane przy pomocy
    'admin-forward', czyli poprzez załadowanie strony pośredniej 
    http://admin.salon24.pl/posts z odpowiednio ustawionym linkiem do kotwicy
    (#j-*), co skrypt przechwytuje i dokonuje kolejnego skoku do docelowego
    urla.  Dodatkowo mechanizm "przechwytuje" naciśnięcie 'Back' w
    przeglądarce, żeby na owej podstronie pośredniej się nie zapętlać.

*/

s25.parsemeta = function (cdata) {
  res = {};
  lines = cdata.split('\n');
  var m = new RegExp(/\s*\/\/\s*@([a-zA-Z]+)\s+(.*)/);
  for(var l=0;l<lines.length;l++) {
    if(lines[l].match(m))
      res[lines[l].replace(m,'$1')] = lines[l].replace(m,'$2');
  }
  return res;
}


s25.init = function () {
  
  $ = unsafeWindow.$;

  if(typeof(s25.state) != 'undefined') {
    alert('Salon25 zainstalowany dwukrotnie (najprawdopodobniej jako dodatek Firefoksa i jako skrypt greasemonkey). Pozbądź się jednej wersji. Menu: Narzędzia->Dodatki');
    return 1;
  }
  
  //s25.meta = s25.parsemeta(s25.metas);

  
  if(GM_getValue('blogroll_reorder',false )) {
    $('head').append(s25.elem('link', {href:'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.3/themes/base/jquery-ui.css', rel:'stylesheet', type:'text/css'})); 
    $('head').append(s25.elem('script', {src:'http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.3/jquery-ui.min.js', type:'text/javascript'})); 
  }

  s25.state = {
    is_logged : false,
    my_domain : undefined,
    blog_domain : undefined,
    blog_author_id : undefined,
    blog_author_name : undefined,
    post_id : undefined,
    
    watched_new_answers : -1,
    watched_first_link : undefined,
    watched_first_title : 0,
    watched_link : undefined,
    watchedcount_link : undefined,
    watched_cache : undefined,

    newmails : 0,
    newmails_li : undefined,

    add_to_fav : undefined,
    default_menu_names : {},
    advanced_menu_magic : 0,

    comment_template: GM_getValue('comment_template', false),
    comment_template_title: GM_getValue('comment_template_title', ''),
    comment_template_content: GM_getValue('comment_template_content', ''),

    is_ff_extension : false, //FIXME: should be set to true value (if we are extesion not raw GM script)
  };

  s25.domain = unsafeWindow.Service.cookieDomain || unsafeWindow.Service.cookie_domain;
  s25.admin_domain = unsafeWindow.Service.adminDomain || 'admin.' + s25.domain;

  GM_log('domain: ' + s25.domain);

  s25.consts = {
    show_last_hash : '#show-last-',
    watch_page_url : 'http://' + s25.admin_domain + '/posts-comments-watch/',
    postedit_page_url : 'http://' + s25.admin_domain + '/posts-edit/',
    quote_start : "<i>",
    quote_end : "</i>",
    project_url : 'http://code.google.com/p/salon25/',
    admin_url : 'http://' + s25.admin_domain + '/',
    admin_goto_url : 'http://' + s25.admin_domain + '/posts#j-',
    admin_goto_hash : 'j-',
    update_delay : GM_getValue("update_delay", 60),
    version_check_url : "https://salon25.googlecode.com/svn/wiki/Wersja.wiki",
    default_blogroll : ['my-content', 'my-last-in-newspapers', 'my-last-posts', 'my-last-comments', 'my-popular-posts', 'my-last-discussions'], //'my-archive', 'my-tags'
  };


  s25.media = { 
    //xxd -i lock.png | xargs echo | sed -e 's/0x/%/g' -e 's/, //g' -e 's/%50%4e%47/PNG/g'
    lock :  "data:image/png,%89PNG%0d%0a%1a%0a%00%00%00%0d%49%48%44%52%00%00%00%10%00%00%00%10%02%03%00%00%00%62%9d%17%f2%00%00%00%01%73%52%47%42%00%ae%ce%1c%e9%00%00%00%0c%50%4c%54%45%79%79%79%a0%a0%a0%ca%ca%ca%ff%ff%ff%00%e3%1d%01%00%00%00%34%49%44%41%54%08%d7%63%f8%0f%04%0c%10%e2%49%3d%90%98%1e%0d%24%a2%a7%03%89%fc%e7%40%c2%fe%f3%7f%86%3f%0c%0c%40%62%d5%0a%20%31%73%06%0a%01%16%03%c9%c2%4d%01%00%30%a4%33%ca%33%2a%d7%03%00%00%00%00%49%45%4e%44%ae%42%60%82",
    throbbericon :"data:image/gif,GIF89a%0D%00%0D%00%84%1E%00%00%00%00%08%73%BD%0C%7B%BD%18%7B%C6%1C%84%C6%35%90%CA%46%9C%CE%5A%A2%D3%6B%AF%D8%8B%BF%E1%B5%B5%B5%A0%CE%E7%B5%D6%EF%BD%BD%BD%BD%DE%EF%C6%C6%C6%CE%CE%CE%D6%D6%D6%DE%DE%DE%CA%E2%F3%D6%E7%F7%DE%EF%F7%E7%E7%E7%E7%EF%F7%E7%F7%FF%EF%EF%EF%EF%F7%FF%F7%F7%F7%F7%F7%FF%F7%FF%FF%FF%FF%FF%FF%FF%FF%21%FF%0B%4E%45%54%53%43%41%50%45%32%2E%30%03%01%00%00%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%59%E0%27%7E%54%82%2C%D5%38%56%46%E0%BA%87%B6%0A%81%40%04%37%CE%89%6D%51%25%81%C4%E4%86%20%D5%2E%1E%60%C2%33%71%69%16%01%84%27%19%9C%B6%18%88%2A%75%E9%C9%26%80%52%0F%E3%C0%B0%06%18%94%E3%74%DD%0C%C8%7A%15%F6%20%2A%AA%D0%02%06%44%4B%37%BA%EC%5F%08%32%2A%24%0B%27%29%23%21%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%47%E0%27%7E%D3%92%7C%DA%A8%AE%22%37%5E%C4%17%14%47%21%16%E9%EA%71%44%30%BC%2A%4F%22%60%70%88%2E%AB%8A%4C%69%73%9C%10%A2%83%4A%BA%58%7C%A4%9F%0B%C2%35%72%4C%64%2C%91%C0%33%8A%75%59%E6%AB%ED%B3%0E%47%91%2B%E4%69%15%02%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%3F%E0%27%7E%D7%58%8D%63%89%8A%EA%77%8A%C6%CA%AD%A2%E7%4D%C2%38%7D%C1%E8%39%85%9E%C0%23%3A%B0%8C%01%02%0D%25%48%D0%10%28%55%81%F5%C9%AD%1C%BC%56%61%27%E2%A6%46%D3%98%48%63%5A%CE%56%5E%F2%28%04%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%48%E0%27%7E%54%82%8C%E8%57%A5%A2%86%0A%1F%8C%18%22%C1%A6%B6%48%C5%A8%E7%4D%9F%80%EB%73%FA%38%12%C8%84%8D%71%4A%88%9C%81%68%E0%83%44%31%0E%D8%C3%72%77%03%7E%86%A2%D5%4D%05%FB%18%8A%1F%02%67%74%61%21%C0%A3%DD%49%2C%0A%01%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%49%E0%27%7E%D3%92%7C%DA%A8%AE%22%37%5E%C4%17%14%C7%58%A4%6C%7E%E5%9F%23%EE%AA%0B%E2%E2%F1%14%7A%27%84%A8%26%48%78%6A%8B%C5%A7%F6%D9%05%02%84%A3%63%22%53%39%0A%81%8F%C0%33%8A%8D%1C%82%95%79%7A%FC%B4%79%53%60%F0%73%5A%85%00%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%40%E0%27%7E%D7%58%8D%63%89%8A%EA%77%8A%C6%57%8C%DC%BA%0E%E3%F4%05%B6%2E%78%A2%03%AA%F6%89%D9%44%09%E0%0A%21%AA%F0%2A%4A%D2%47%30%4A%04%0C%8E%5D%AB%A0%E3%10%78%A8%ED%4A%63%3A%12%51%3A%11%79%14%02%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%45%E0%27%7E%D4%87%8C%E8%57%A5%A2%86%0A%1F%8C%18%22%C1%A6%B6%58%C2%77%E0%9A%22%47%C2%81%62%9C%12%22%E4%E8%A8%4C%7E%12%9E%0F%8D%51%1A%25%02%D0%49%0B%55%B9%26%26%03%2E%8F%10%C8%11%38%A3%0B%0B%F1%43%95%4E%AB%51%08%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%46%E0%27%7E%D3%97%7C%DA%A8%AE%22%37%5E%C4%17%14%C7%58%A4%6C%7E%E5%9F%23%EE%AA%0B%02%57%E8%9D%10%A2%1A%F2%53%5B%2C%98%BD%80%00%27%72%94%02%9F%42%60%E1%19%09%BA%A2%C1%CC%E3%F1%AD%62%D9%43%31%CB%1B%1D%80%41%13%2B%04%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%41%E0%27%7E%D7%58%8D%63%89%8A%EA%77%8A%C6%57%8C%DC%BA%0E%E3%F4%05%B6%2E%78%A2%83%E8%54%FB%C4%50%9C%04%CF%06%23%F0%10%A3%19%49%14%30%50%80%1F%C7%AE%45%98%60%75%A8%16%6C%A4%31%31%8B%28%F0%A7%3C%0A%01%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%49%E0%27%7E%54%82%8C%E8%57%A5%A2%86%0A%1F%8C%18%22%C1%A6%B6%48%C5%F7%17%68%89%0F%E1%40%3C%30%50%8C%53%60%29%0A%7E%4E%CE%42%62%9A%70%88%68%8C%9D%E0%E2%F1%8C%26%AD%51%61%D5%AB%C0%3E%86%53%8D%33%BA%B0%10%AE%D4%EE%44%16%85%00%00%21%F9%04%05%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%48%E0%27%7E%D3%92%7C%DA%A8%AE%22%37%5E%C4%17%14%C7%58%A4%63%CC%8A%97%1C%18%94%91%83%B7%F8%18%08%81%00%02%57%F8%38%4E%08%CE%E9%83%10%D5%8A%9F%83%C7%53%89%AA%1C%13%D9%EE%23%F0%E4%BE%2C%5D%B6%F9%61%8F%B3%BD%55%6F%AA%0A%01%00%21%F9%04%01%06%00%1F%00%2C%00%00%00%00%0D%00%0D%00%00%05%41%E0%27%7E%D7%58%8D%63%89%8A%EA%77%A2%C5%C8%AD%41%2C%0E%E3%C4%16%C1%22%EA%02%8F%E8%E0%71%7C%04%23%C3%CA%E3%39%AC%50%08%D6%47%23%B2%95%90%2B%63%A0%55%D0%FD%56%DC%8F%52%44%15%BD%56%B3%95%77%8A%0A%01%00%3B",
  };


  s25.debug = {
    verbose : 0,
    time : 0,
    time_start: undefined,
  };

  String.prototype.ssplit = function(elem, cnt) {
    if(s25.undef(elem)) elem = " ";
    var tmp = this.split(elem);
    return tmp.slice(0, cnt).concat(tmp.slice(cnt).join(elem));
  }


}

s25.debug_time = function (msg) {
  if(!s25.debug.time)
    return;
  d=new Date();
  if(!s25.debug.time_start) {
    s25.debug.time_start = d.getTime();
    //GM_log('TIMESTAMP time_start is ' + s25.debug.time_start);
  }
  diff = (d.getTime() - s25.debug.time_start);
  GM_log('TIMESTAMP ' + diff + ' #' + msg);
}

s25.log = function (msg, verbose) {
  if(!verbose && !s25.debug.verbose)
    return;
  GM_log(msg);
}


//obsługa "admin-forward"
s25.process_url = function () {
  gotolen = s25.consts.admin_goto_hash.length;
  //s25.log('hash: ' + document.location.hash.slice(0,gotolen+1) + ' ' + document.location.hash.slice(gotolen+1));

  if(document.location.hash == '#favpostok') {
    //window.location.hash = "";
    to = window.location.href.replace(/#.*/,'#');
    window.location.replace(to);
    return 1;
  }

  //jeśli właśnie weszliśmy do skrzynki odbiorczej, to nie mamy "nowej" poczty
  if(document.location.href == s25.consts.admin_url + 'mail/') {
    //s25.state.newmails = 0;
    GM_setValue("newmails", 0);
  }


  if(document.location.hash.slice(0,gotolen+1) == '#' + s25.consts.admin_goto_hash) {
    to = document.location.hash.slice(gotolen+1);

    dest = 'back';
    if(to.indexOf(dest) == 0 && dest.length == to.length) {
      window.history.go(-2);
      return 1;
    }

    gotourl = null;

    dest = 'mail-new/';
    if(to.indexOf(dest) == 0) {
      uid = parseInt(to.slice(dest.length));
      if(!uid || uid<0)
	return -1;
      gotourl = s25.consts.admin_url + dest + uid;
    }

    dest = 'posts-edit/';
    if(to.indexOf(dest) == 0) {
      if(dest.length == to.length) 
	gotourl = s25.consts.admin_url + dest;
      else {
	pid = parseInt(to.slice(dest.length));
	if(!pid || pid<0)
	  return -1;
	gotourl = s25.consts.admin_url + dest + pid;
      }
    }

    if(gotourl) {
      //s25.log('going to: ' + gotourl);
      document.location.replace(gotourl);
      //document.location.hash = s25.consts.admin_goto_hash + 'back';
      //document.location = gotourl;
      return 1;
    }
  }

  if(document.location.href == 'http://www.' + s25.domain + '/static/about#mclose')  
  {
    GM_log('close');
    unsafeWindow.parent.Service.login();
    window.close();

  }
  if(document.location.href == 'http://www.' + s25.domain + '/static/about#mlogin') 
  {
    $('div#body').remove();
    $('login-burl').attr('value', 'http://www.' + s25.domain + '/static/about#mclose');
    $('login-burl').attr('value', 'http://www.' + s25.domain + '/static/about#mclose');
    $('#jqmLogin').css('left', '0').css('margin-left', '0').css('top', '0');

    unsafeWindow.Service.login('http://www.' + s25.domain + '/static/about#mclose','http://www.' + s25.domain + '/static/about#mclose');
  }


  return 0;
}


s25.update_iframe = function () {

  if(document.location.host == s25.admin_domain) 
    return;
  if(document.location.host == 'www.' + s25.domain) 
    return;
  ifr = s25.elem('iframe', {id: 'ifr', style: {border: '0'}, scrolling: 'no', src: 'http://www.' + s25.domain + '/static/about#mlogin'});

  ifdiv = s25.elem('div',  {className: 'jqmWindow'}, $(ifr).width(424).height(262));
  $('body').append($(ifdiv).width(424).show());
  setTimeout(function () { GM_log(ifr.contentDocument.location);}, 1000);

  //ifr.src = 'http://www.' + s25.domain + '/contact/';
  //ifr.contentDocument.location =  s25.consts.admin_url + 'mail-new/1234';
  //GM_log(inside.Service);
  //GM_log(unsafeWindow.inside.Service);

}


s25.check_is_logged = function () {
  var cookies = document.cookie.split(' ');

  s25.state.my_domain = undefined;
  s25.state.is_logged = false;

  if(unsafeWindow.Service.isLogin()) {
    if($.cookie('s_us_name')) {
      s25.state.is_logged = true;
      s25.state.my_domain = $.cookie('s_us_name');
    }
  }

/*
  for(c=0;c<cookies.length;c++) {
    cookie = cookies[c].split('=');
    if(cookie[0] == 's_us_name') {
      s25.state.my_domain = cookie[1];
      s25.state.is_logged = true;
      //s25.log('my domain: ' + s25.state.my_domain);
    }
  }
  */
}

s25.get_my_info = function () {
  //page load error
  if(!document.domain)
    return -1;

  var cookies = document.cookie.split(' ');
//  s25.log(document.cookie);

  s25.state.blog_domain = document.domain.replace(/^www\./,'');
  s25.log('blog domain: ' + s25.state.blog_domain);

  for(c=0;c<cookies.length;c++) {
    cookies[c] = cookies[c].replace(/;$/,'');
    //s25.log('cookie: ' + cookies[c]);
  }

  s25.check_is_logged();

  postinfo = s25.getElementByClass('post-detal',document,'div');
  if(postinfo) {
      post_id = parseInt(postinfo.id.replace(/^post-/,''));
      if(post_id >0) {
	s25.state.post_id = post_id;
	s25.log('post_id: ' + s25.state.post_id);
      }
  }

  authorinfo = s25.getElementByClass('ui-icon ui-icon-heart', document.getElementById('thisblog'), 'span');
  if(authorinfo) {
    blog_author_id = parseInt(authorinfo.parentNode.getAttribute('onclick').replace(/.*\(([0-9]+),.*\)/,'$1'));
    if(blog_author_id > 0) {
      s25.state.blog_author_id = blog_author_id;
      s25.log('blog_author_id: ' + s25.state.blog_author_id);
    }
  }

  author = document.getElementById('blog-user');
  if(author) {
    h1 = author.getElementsByTagName('h1');
    if(h1.length) 
      h = h1[0];
    else
      h = author.getElementsByTagName('h2')[0];
    if(h.getElementsByTagName('a').length)
      blog_author_name = h.getElementsByTagName('a')[0].innerHTML;
    else
      blog_author_name = h.innerHTML;
    if(blog_author_name) {
      s25.state.blog_author_name = blog_author_name;
      s25.log('blog_author_name: ' + s25.state.blog_author_name);
    }
  } else {
    if(unsafeWindow.Service.newspaperOID>0) {
      //blog author is CAPITALIZED here. sucks
      s25.state.blog_author_name = $("div.post-detal>div.author>div.author-about-body>a.author-nick").text();
    }
  }
}

s25.count_watched = function (doc) {

  if(document.location.href.slice(0,s25.consts.watch_page_url.length) == s25.consts.watch_page_url) {
    if(s25.state.watched_cache)
      newcomments = s25.state.watched_cache;
    else
      s25.state.watched_cache = newcomments = s25.parse_watched(doc);
  } else
    newcomments = s25.parse_watched(doc);

  serialize = "";

  s25.state.watched_new_answers = 0;
  for(c=0; c<newcomments.rows.length;c++) {
    s25.state.watched_new_answers += (newcomments.rows[c].ncomments != 0);
    if(newcomments.rows[c].ncomments)
      serialize = (serialize ? (serialize + ":") : "") + newcomments.rows[c].id + '=' + newcomments.rows[c].ncomments;
    //s25.state.watched_new_answers += newcomments.rows[c].ncomments;
  }
  if(s25.state.watched_new_answers > 0) {
    s25.state.watched_first_link = newcomments.rows[0].link + s25.consts.show_last_hash + newcomments.rows[0].ncomments;
    s25.state.watched_first_title = newcomments.rows[0].title + ' (' + newcomments.rows[0].ncomments + ')';
    GM_setValue("watched_first_link", s25.state.watched_first_link);
    GM_setValue("watched_first_title", s25.state.watched_first_title);
  }
  GM_setValue("watched_serialize", serialize);
  GM_setValue("watched_new_answers", s25.state.watched_new_answers.toString());
}


s25.recheck_status = function (force) {
  //s25.log('s25.recheck_status @' + new Date().toTimeString());

  now = new Date().getTime();
  last_check = parseInt(GM_getValue("recheck_time", 0));
  if(force || now - last_check >= s25.consts.update_delay * 1000) {
    //ustaw timer od razu, żeby nie rozpocząć dwóch sprawdzań równolegle
    GM_setValue("recheck_time", now.toString());
    s25.loadPage(s25.consts.watch_page_url, s25.onload_watch_page_info);
  } else {
    //GM_log("-cached-");
    s25.state.watched_first_link = GM_getValue("watched_first_link");
    s25.state.watched_first_title = GM_getValue("watched_first_title");
    s25.state.watched_new_answers = GM_getValue("watched_new_answers",0);
    s25.state.newmails = GM_getValue("newmails",0);
    s25.update_ui();
  }
}

s25.loop_recheck_status = function () {
  
  s25.check_is_logged(); //is_logged może się zmienić w trakcie sesji (wylogowanie z innego okna przeglądarki)
  if(!s25.state.is_logged) 
    return;

  s25.recheck_status(false);

  //sprawdza czterokrotnie w ciągu update_delay (bo może inny wątek odświeżył)
  delay = s25.consts.update_delay * 1000 / 4;
  if(delay<1000) delay = 1000;

  setTimeout(s25.loop_recheck_status, delay);
}

/* Przegląda zapamietane informacje o obserwowanych stronach
 * Jeśli aktualnie wszedłem na jedną ze stron obserwowanych to uznaje, że wszystkie komentarze na niej
 * zostały obejrzane, więc kasuję tę notkę z listy */
s25.offline_update_watched = function () {
  if(s25.state.post_id) {
    serialize = GM_getValue("watched_serialize","");
    //s25.log("serialize: " + serialize,1);
    watched = serialize.split(':');
    for(w=0, match=false, newserialize="";w<watched.length;w++){
      //s25.log("watched: "+ watched[w],1);
      ar = watched[w].split('=');
      id = parseInt(ar[0]);
      count = parseInt(ar[1]);
      if(id == s25.state.post_id) 
       match = true;
      else 
	//budujemy nową listę pomijając czytaną właśnie notkę
	newserialize = (newserialize ? (newserialize + ':') : "") + watched[w];
    }
    if(match) {
      //s25.log("newserialize: " + newserialize,1);
      //natychmiast zmieniamy to co wiemy
      GM_setValue("watched_serialize", newserialize);
      GM_setValue("watched_new_answers", watched.length-1);
      //wymusamy ponowne sprawdzenie strony obserwowanych (żeby otrzymać nowe linki/tytuły)
      s25.recheck_status(true);
    }
      
  }
}

s25.get_account_info = function () {
  if(!s25.state.is_logged)
    return 0;

  if(document.location.href.slice(0,s25.consts.watch_page_url.length) == s25.consts.watch_page_url)
    s25.analyze_watch_page_info(document);
  else 
    s25.offline_update_watched();

  if(s25.consts.update_delay > 0)
    s25.loop_recheck_status();
}

s25.onload_watch_page_info = function (responseDetails) {
  xmlDoc = new DOMParser().parseFromString(responseDetails.responseText, 'text/xml');
  s25.analyze_watch_page_info(xmlDoc);
}

s25.analyze_watch_page_info = function (doc) {
  //s25.log("s25.analyze_watch_page_info",1);

  s25.count_watched(doc);
  
  tds = s25.getElementsByClass('new_mails', doc, 'span');
  s25.state.newmails = tds.length;
  GM_setValue("newmails", s25.state.newmails.toString());

  //ustaw timer w momencie zakoćzenia sprawdzania
  GM_setValue("recheck_time", new Date().getTime().toString());
  s25.update_ui();
}


//wersja XPath działa ładnie dla 'document', ale nie działa dla XMLa wygenerowanego z wyniku GM_xmlhttpRequest :(
s25.parse_watched_xpath = function (dom) {
  var newcomm = new Array();
  var nc = 0;

  query = "//div[@id='posts-comments-watch']//tr[@id]";
  watchrows = dom.evaluate(query, dom.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  //watchrows = dom.evaluate(query, dom.getElementById('posts-comments-watch'), null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  s25.log(watchrows.snapshotLength);
  for (i = 0; i < watchrows.snapshotLength; i++) {
    var row = watchrows.snapshotItem(i);
    newcomm[nc] = new Object();
    newcomm[nc].id = row.id.slice(row.id.indexOf('-')+1);
    columns = row.getElementsByTagName('td');
    info = columns[0].getElementsByTagName('a')[0];
    newcomm[nc].title = info.innerHTML;
    newcomm[nc].link = info.href;
    newcomm[nc].ncomments = parseInt(columns[3].innerHTML);
    newcomm[nc].row = row;
    
    //s25.log('watched: ' + newcomm[nc].id + ' ' + newcomm[nc].ncomments + ' '+ newcomm[nc].link + ' ' + newcomm[nc].title);

    nc++;
  }
  return newcomm;
}

s25.parse_watched = function (dom) {
  var newcomm = new Object();
  newcomm.rows = new Array();
  newcomm.sel = new Array();
  var nc = 0;

  //wiersze tabeli z niepustą nazwą klasy
  //rows =  s25.getElementsByCondition(function(el){if(el.className) return el;}, dom.getElementById('posts-comments-watch'), 'tr');
  var rows = $(dom).find('#posts-comments-watch tr');

  for (i = 0; i < rows.length; i++) {
    var row = rows[i];
    if(!row.className) 
      newcomm.header = row;
    else {
      newcomm.rows[nc] = new Object();
      newcomm.rows[nc].id = row.id.slice(row.id.indexOf('-')+1);
      columns = row.getElementsByTagName('td');
      info = columns[1].getElementsByTagName('a')[0];
      newcomm.rows[nc].title = info.innerHTML;
      newcomm.rows[nc].link = info.href;
      newcomm.rows[nc].ncomments = parseInt(columns[4].innerHTML);
      newcomm.rows[nc].xdate = Date.parse(columns[3].innerHTML.replace(/-/g,'/'));
      newcomm.rows[nc].row = row;
      //s25.log('watched: ' + newcomm.rows[nc].id + ' ' + newcomm.rows[nc].ncomments + ' '+ newcomm.rows[nc].link + ' ' + newcomm.rows[nc].title);

      nc++;
    }
  }
  return newcomm;
}

s25.lprunning = 0;

s25.event_watched_del_done = function (responseDetails) {
  s25.lprunning--;
  s25.log('lpdone, running: ' + s25.lprunning);
}

s25.islpdone = function (whendone, timeouts, wait) {
  s25.log('timeout ' + wait + ' x ' + timeouts + ' lprunning ' + s25.lprunning);
  
  if(timeouts<=0 || s25.lprunning<=0) {
    whendone();
    return 0;
  }

  setTimeout(function () {s25.islpdone(whendone, --timeouts, wait);}, wait);
}


s25.update_fck = function (editroInstance) {
  //fck = FCKeditorAPI.GetInstance('content-textarea');
  fck = editroInstance;
  //fck.SwitchEditMode();
  fck.Config.ToolbarSets.Default25 = fck.Config.ToolbarSets.Default.slice();
  fck.Config.ToolbarSets.Default25.push(new Array("Source"));
  fck.ToolbarSet.Load('Default25');

  if(old_FCKeditor_OnComplete) 
    old_FCKeditor_OnComplete(editroInstance);
}


s25.update_post_edit = function () {
 if(document.location.href.slice(0,s25.consts.postedit_page_url.length) != s25.consts.postedit_page_url)
    return;

  old_FCKeditor_OnComplete = undefined;
  if(unsafeWindow.FCKeditor_OnComplete)
    old_FCKeditor_OnComplete = unsafeWindow.FCKeditor_OnComplete;

  s25.log('s25.update_post_edit', 1);
  unsafeWindow.FCKeditor_OnComplete = s25.update_fck;
}

s25.update_watched_page = function () {
  if(document.location.href.slice(0,s25.consts.watch_page_url.length) != s25.consts.watch_page_url)
    return;

  if(!s25.state.watched_cache)
    s25.state.watched_cache = s25.parse_watched(document);

  for (i = 0; i < s25.state.watched_cache.rows.length; i++) {
    watch = s25.state.watched_cache.rows[i];

    //dodaj link do pierwszego niewidzianego komentarza
    if(watch.ncomments>0) {
      a = s25.createLink(watch.link + s25.consts.show_last_hash + watch.ncomments, watch.ncomments.toString());
      a.style.color = 'inherit';
      td = watch.row.getElementsByTagName('td')[4];
      td.replaceChild(a,td.firstChild)
    }


  }

  //sortowanie obserwowanych według postów *i daty powstania notki*
  //(tylko jeśli nie włączono żadnych opcji sortowania)
  if(document.location.href == s25.consts.watch_page_url) {
    wrsort = function (a,b) { 
      if(a.ncomments != b.ncomments)
	return b.ncomments - a.ncomments;
      else 
	return b.xdate - a.xdate;
    };

    s25.state.watched_cache.rows.sort(wrsort);

    watchtable = document.getElementById('posts-comments-watch').getElementsByTagName('table')[0];
    while(watchtable.rows.length>1)
      watchtable.deleteRow(1);

    tbody = watchtable.getElementsByTagName('tbody')[0];
    for (i = 0; i < s25.state.watched_cache.rows.length; i++) {
      s25.state.watched_cache.rows[i].row.className = 'r' + i%2;
      tbody.appendChild(s25.state.watched_cache.rows[i].row);
    }
  }


}

s25.update_post_in_lc = function () {

  if(!unsafeWindow.Service.newspaperOID)
    return;

  var author = $('div#content div.content-right div.author-about-body>a.author-nick');
  if(!author.length) return;

  var blog = author[0].href;
  var href = blog + window.location.pathname.replace(/.*\//,"");



  if(0) {

    var title = $('div.content-left div.post-detal h1');

    var link = s25.createLink(href, "»");
    link.style.color = 'blue';

    var hover = s25.elem('div', { style: { position: "absolute", display: 'none', zIndex: 1000, height: '100%', bottom: '0em', right: '0px', color: 'blue', backgroundColor: "#ddd", padding: '3px' }, id: 'notelink' }, [link]);

    $(hover).mouseover(function (e) { $('#notelink').dequeue().show(); } );
    $(hover).mouseout(function (e)  { $('#notelink').fadeOut('slow'); } );
    title.mouseover(function (e) { $('#notelink').dequeue().show(); } );
    title.mouseout(function (e)  { $('#notelink').fadeOut('slow'); } );
    title.css('position', 'relative');
    title.append(hover);
  } else {

    $('div.post_tags').append(' | Notka ', s25.elem('a', { href: href }, [ "na blogu autora" ]));


  }



}

s25.update_post_permalink = function () {
  //łatwy dostęp do permalinku gdy adresem notki jest adres bloga
  if(document.location.pathname == '/') {

    last_posts = document.getElementById('my-last-posts');
    if(!last_posts) return;
   
    li = last_posts.getElementsByTagName('li');
    if(!li) return;

    h2 = li[0].getElementsByTagName('h2');
    if(!h2) return;

    a = h2[0].getElementsByTagName('a');
    if(!a) return;

    title = a[0].innerHTML;
    link  = a[0].href;

    h1 = document.getElementById('post-' + s25.state.post_id).getElementsByTagName('h1');
    if(!h1) return;

    posttitle = h1[0].innerHTML;
    if(title == posttitle) {
      ta = s25.createLink(link,posttitle);
      ta.style.color = 'inherit';
      ta.style.textDecoration = 'none';
      h1[0].replaceChild(ta, h1[0].firstChild);
    }
  }
}

s25.update_post = function () {
  //dodaj możliwośc wysłania wiadomości do właściciela bloga i banowania autora
  if(s25.state.blog_author_id) {
    rightcolumn = s25.getElementByClass('content-right',document.getElementById('content'),'div');
    mailto = s25.createLink(s25.consts.admin_goto_url + 'mail-new/' + s25.state.blog_author_id, 'wyślij wiadomość do autora bloga');
    mailto.style.backgroundImage = 'url(http://s.' + s25.domain + '/admin/gfx/icons.gif)';
    mailto.style.backgroundPosition = 'left -87px';
    mailto.style.backgroundRepeat = 'no-repeat';
    mailto.style.paddingLeft = '20px';
    //mailto.style.textDecoration = 'none';
    mailto.innerHTML='wyślij wiadomość do autora';

    ban = s25.createLink('#lock-user-' + s25.state.blog_author_id, 'zablokuj autora na swoim blogu');
    ban.title = 'dodaj do listy zablokowanych użytkowników';
    ban.style.backgroundImage = 'url(' + s25.media.lock + ')';
    //ban.style.backgroundPosition = 'left -63px';
    ban.style.backgroundRepeat = 'no-repeat';
    ban.style.paddingLeft = '20px';
    //ban.style.textDecoration = 'none';
    ban.setAttribute('user_to_lock', s25.state.blog_author_id);
    s25.addEvent(ban, 'click', function(e) { id=this.getAttribute('user_to_lock'); unsafeWindow.Service.lockUserPopup(id); e.preventDefault(); } );


    div = document.createElement('div');
    div.className = 'box';
    div.appendChild(mailto);
    div.appendChild(document.createElement('br'));
    div.appendChild(ban);

    rightcolumn.appendChild(div);
  }

  //podmień obsługę 'dodaj do obserwowanych'
  if(s25.state.post_id) {
    s25.state.add_to_fav = s25.getElementByClass('ico_add_to_favorite', document, 'a');
    if(s25.state.add_to_fav) {
      s25.state.add_to_fav.removeAttribute('onclick');
      s25.addEvent(s25.state.add_to_fav, 'click', function(e) { s25.event_add_fav_post(s25.state.post_id); e.preventDefault(); } );
    }
  }


  s25.update_post_permalink();
  s25.update_post_in_lc();
}

// misc functions
//

var URL = {

  matches : function() {
    var ret = false;
    for(var i=0; i<arguments.length;i++) {
      if(document.location.href.match(arguments[i]) != null) {
        ret = true;
        break;
      } 
    }
    return ret;
  }

};

s25.undef = function (obj) {
  return typeof(obj)=='undefined';
}

s25.elem = function (tag, params, childNodes) { 
  // deprecated. use s25.el
  // todo: refactor code to use s25.el
  if(typeof(childNodes)=='undefined') childNodes = [];
  if(typeof(params)=='undefined') params = {};

  var ret = document.createElement(tag);
  for(var param in params) {
    if(typeof(params[param])=='string') {
      ret[param] = params[param];
    } else if(typeof(params[param])=='function') {
      s25.addEvent(ret, param, params[param]);
    } else {
      for(var k in params[param]) {
        ret[param][k] = params[param][k];
      }
    }
  }

  for(var i=0;i<childNodes.length;i++) {
    if(typeof(childNodes[i]) == 'string')
      ret.appendChild(document.createTextNode(childNodes[i]));
    else
      ret.appendChild(childNodes[i]);
  }

  return ret;
}

s25.el = function () { 
  var args = Array.prototype.slice.call(arguments);
  var tag = args[0];
  var params = args.length>1 ? args[1] : {};
  var childNodes = args.length>2 ? args.slice(2) : [];

  var ret = document.createElement(tag);
  for(var param in params) {
    if(typeof(params[param])=='string') {
      ret[param] = params[param];
    } else if(typeof(params[param])=='function') {
      s25.addEvent(ret, param, params[param]);
    } else {
      for(var k in params[param]) {
        ret[param][k] = params[param][k];
      }
    }
  }

  for(var i=0;i<childNodes.length;i++) {
    if(typeof(childNodes[i]) == 'string')
      ret.appendChild(document.createTextNode(childNodes[i]));
    else
      ret.appendChild(childNodes[i]);
  }

  return ret;
}

s25.parseHtmlResponse = function (response) {

	response = response.responseText.split('\n');
	var res = [];
	for(var i=0;i<response.length;i++) {
		if(response[i].match('<body.*>')) {
			i++;
			break;
		}
	}

	for(;i<response.length;i++) {
		if(response[i].match('</body>')) break;
		res[res.length] = response[i];
	}

	res = res.join('\n');
	var div = document.createElement('div');
	div.innerHTML = res;

	return div;
}

s25.super_hack = function () {
  var x = document.createElement('script');
  x.type = "text/javascript";
  x.src = chrome.extension.getURL('script.js');
  document.head.appendChild(x);
}

var gvar=function() {} // Global variables
s25.GM_ApiBrowserCheck = function () {
  const GMSTORAGE_PATH = 'GM_'; // You can change it to avoid conflict with others scripts
  if(typeof(unsafeWindow)=='undefined') { unsafeWindow=window; }
  if(typeof(GM_log)=='undefined') { GM_log=function(msg) { try { unsafeWindow.console.s25.log('GM_log: '+msg); } catch(e) {} }; }
  GM_clog=function(msg) { if(arguments.callee.counter) { arguments.callee.counter++; } else { arguments.callee.counter=1; } GM_log('('+arguments.callee.counter+') '+msg); }
  GM_addGlobalStyle=function(css) { // Redefine GM_addGlobalStyle with a better routine
    var sel=document.createElement('style'); sel.setAttribute('type','text/css'); sel.appendChild(document.createTextNode(css));
    var hel=document.documentElement.firstChild; while(hel && hel.nodeName!='HEAD') { hel=hel.nextSibling; }
    if(hel && hel.nodeName=='HEAD') { hel.appendChild(sel); } else { document.body.insertBefore(sel,document.body.firstChild); }
    return sel;
  }
  var needApiUpgrade=false;
  if(window.navigator.appName.match(/^opera/i) && typeof(window.opera)!='undefined') {
    needApiUpgrade=true; gvar.isOpera=true; GM_log=window.opera.postError; GM_log('Opera detected...');
  }
  if(typeof(GM_setValue)!='undefined') {
    var ff4 = typeof(GM_setValue.toString) == 'undefined'; // Firefox 4 lost function.toString(), so let's assume this is Firefox 4
    var gsv=ff4?'staticArgs':GM_setValue.toString();
    if(gsv.indexOf('staticArgs')>0) { gvar.isGreaseMonkey=true; if(0) GM_log('GreaseMonkey Api detected...'); } // test GM_hitch
    else if(gsv.match(/not\s+supported/)) { needApiUpgrade=true; gvar.isBuggedChrome=true; GM_log('Bugged Chrome GM Api detected...'); }
  } else { needApiUpgrade=true; GM_log('No GM Api detected...'); }

  if(needApiUpgrade) {
    GM_log('Try to recreate needed GM Api...');
    var ws=null; try { ws=typeof(unsafeWindow.localStorage); unsafeWindow.localStorage.length; } catch(e) { ws=null; } // Catch Security error
    if(ws=='object') {
      GM_log('Using localStorage for GM Api.');
      GM_getValue=function(name,defValue) { var value=unsafeWindow.localStorage.getItem(GMSTORAGE_PATH+name); if(value==null) { return defValue; } else { switch(value.substr(0,2)) { case 'S]': return value.substr(2); case 'N]': return parseInt(value.substr(2)); case 'B]': return value.substr(2)=='true'; } } return value; }
      GM_setValue=function(name,value) { switch (typeof(value)) { case 'string': unsafeWindow.localStorage.setItem(GMSTORAGE_PATH+name,'S]'+value); break; case 'number': if(value.toString().indexOf('.')<0) { unsafeWindow.localStorage.setItem(GMSTORAGE_PATH+name,'N]'+value); } break; case 'boolean': unsafeWindow.localStorage.setItem(GMSTORAGE_PATH+name,'B]'+value); break; } }
      GM_deleteValue=function(name) { unsafeWindow.localStorage.removeItem(GMSTORAGE_PATH+name); }
    } else if(!gvar.isOpera || typeof(GM_setValue)=='undefined') {
      GM_log('Using temporarilyStorage for GM Api.'); gvar.temporarilyStorage=new Array();
      GM_getValue=function(name,defValue) { if(typeof(gvar.temporarilyStorage[GMSTORAGE_PATH+name])=='undefined') { return defValue; } else { return gvar.temporarilyStorage[GMSTORAGE_PATH+name]; } }
      GM_setValue=function(name,value) { switch (typeof(value)) { case "string": case "boolean": case "number": gvar.temporarilyStorage[GMSTORAGE_PATH+name]=value; } }
      GM_deleteValue=function(name) { delete gvar.temporarilyStorage[GMSTORAGE_PATH+name]; };
    }
    if(typeof(GM_openInTab)=='undefined') { GM_openInTab=function(url) { unsafeWindow.open(url,""); } }
    if(typeof(GM_registerMenuCommand)=='undefined') { GM_registerMenuCommand=function(name,cmd) { GM_log("Notice: GM_registerMenuCommand is not supported."); } } // Dummy
    if(!gvar.isOpera || typeof(GM_xmlhttpRequest)=='undefined') {
      GM_log('Using XMLHttpRequest for GM Api.');
      GM_xmlhttpRequest=function(obj) {
        var request=new XMLHttpRequest();
        request.onreadystatechange=function() { if(obj.onreadystatechange) { obj.onreadystatechange(request); }; if(request.readyState==4 && obj.onload) { obj.onload(request); } }
        request.onerror=function() { if(obj.onerror) { obj.onerror(request); } }
        try { request.open(obj.method,obj.url,true); } catch(e) { if(obj.onerror) { obj.onerror( {readyState:4,responseHeaders:'',responseText:'',responseXML:'',status:403,statusText:'Forbidden'} ); }; return; }
        if(obj.headers) { for(name in obj.headers) { request.setRequestHeader(name,obj.headers[name]); } }
        request.send(obj.data); return request;
  } } }
}


//// salon 2.0 import
s25.getElementsByCondition = function (condition,container,tag) {
  container = container||document;
  tag = tag||'*';
  var all = container.all||container.getElementsByTagName(tag);
  var arr = [];
  for(var k=0;k<all.length;k++) {
    var elm = all[k];
    if(condition(elm,k)) arr[arr.length] = elm;
  }
  return arr;
} 

s25.getElementsByClass = function (classname, container, tag) {
  var re = new RegExp('\\b'+classname+'\\b');
  return s25.getElementsByCondition(function(el){if(el.className && el.className.match(re)) return el;}, container, tag);
}

s25.getElementByClass = function (classname, container, tag) {
  var re = new RegExp('\\b'+classname+'\\b');
  var ret = s25.getElementsByCondition(function(el){if(el.className && el.className.match(re)) return el;}, container, tag);
  if(ret.length>0) return ret[0];
}
s25.addEvent = function (obj, evType, fn) {
  if(!obj) return false;
  if (obj.addEventListener) {
    obj.addEventListener(evType, fn, false);
    return true;
  } else if (obj.attachEvent) {
    var r = obj.attachEvent("on" + evType, fn);
    return r;
  } else {
    return false;
  }
}

s25.loadPage = function (address, onLoad, onError) {
  //s25.log('GM_xmlhttpRequest(' + address + ')');
  GM_xmlhttpRequest({
    method: 'GET',
    url: address,
    headers: {
      'Cookie': document.cookie,
      //'Accept-Charset': 'ISO-8859-2',
      'X-Requested-With': 'XMLHttpRequest',
    },
    onload: function(responseDetails) {
      //s25.log('status:' + responseDetails.status);
      if(responseDetails.status != 200) {
	//hideLoadingInfo();
	s25.log('status:\n' + responseDetails.status);
	s25.log('statustext:\n'+responseDetails.statusText);
	s25.log('responsetext:\n'+responseDetails.responseText);
	return;
      }	

      if(onLoad) onLoad(responseDetails);
    },
    onerror: function(responseDetails) {
      s25.log('status:\n' + responseDetails.status);
      s25.log('statustext:\n'+responseDetails.statusText);
      s25.log('responsetext:\n'+responseDetails.responseText);
      //hideLoadingInfo();
      if(onError) onError(responseDetails);
    }
  });
}


////
s25.update_ui = function () {
  s25.update_ui_watched();
  s25.update_ui_newmails();
}

s25.update_ui_watched = function () {
  s25.log('new answers: ' + s25.state.watched_new_answers);
  if(!s25.state.watched_link)
    return;
  if(s25.state.watched_new_answers > 0) {
    //s25.state.watched_link.innerHTML = 'obserwowane ('+ s25.state.watched_new_answers + ')';
    s25.state.watched_link.style.color='red';
    s25.state.watchedcount_link.innerHTML = '('+ s25.state.watched_new_answers + ')';
    s25.state.watchedcount_link.href = s25.state.watched_first_link;
    s25.state.watchedcount_link.title = s25.state.watched_first_title;
    s25.state.watchedcount_link.style.display ='inline';


  } else {
    s25.state.watched_link.innerHTML = 'Obserwowane';
    s25.state.watched_link.style.color='';
    s25.state.watchedcount_link.style.display ='none';
  }

  if(GM_getValue('bottom_notification', false)) s25.update_bottom_ui();

}

s25.update_bottom_ui = function () {
  if(s25.state.watched_new_answers > 0) {
    var a = $('#bottom-notification')[0];

    if(!a) {
      a = s25.el('span', 
		     {style:{position:'fixed', color:'red', left:'0px', bottom:'0px', cursor:'pointer'}, 
		      id:'bottom-notification',
		      innerHTML:'Obserwowane ('+s25.state.watched_new_answers+')'});

      s25.addEvent(a, 'click', function() {s25.loadPage(s25.consts.watch_page_url, s25.show_watched);});

      $('body').append(a);
    }

    $(a).show();
    a.innerHTML = 'Obserwowane ('+s25.state.watched_new_answers+')';

  } else {
    $('#bottom-notification').hide();
    $('#new-notes-notification').remove();
  }
}

s25.update_ui_newmails = function () {
  s25.log('new mails: ' + s25.state.newmails);
  if(!s25.state.newmails_li)
    return;
  if(s25.state.newmails > 0)
    s25.state.newmails_li.style.display = 'list-item';
  else
    s25.state.newmails_li.style.display = 'none';
}


s25.createLink = function (url, text, params) {
  if(!params) params = {};
  params.href = url;
  params.innerHTML = text != undefined ? text : url;
  a = s25.elem('a', params);
  return a;
}

s25.hidden_filter2_unlock = function (div) {
  if(!div.firstChild) return;
  t= div.firstChild.data.split('zmień');
  if(t.length!=2) return;
  
  zmien = s25.elem('span', {innerHTML:'zmień'});
  s25.addEvent(zmien, 'click', function (e) { s25.change_filter(2, true); document.location.reload(); });
 
  div.firstChild.replaceWholeText(t[0]);
  $(div.firstChild) .after(document.createTextNode(t[1])) .after(zmien);
}

s25.init_after_s24 = function () {
  $('#cq_mc_re_info').each(function() { s25.hidden_filter2_unlock(this); });
  $('#cq_re_exist').each(function() { s25.hidden_filter2_unlock(this); });
 
  if($('#salon25-config').size())
    $('#navigation').accordion("activate", $('#s25menu'));

  if(s25.state.post_id) {

    //Dla Koteusza, http://koteusz.salon24,pl/310664,wszyscy-klamcy-z-salon24-moje-oswiadczenie
    $('.cq_info_about_filter').each(function (div) { this.innerHTML = this.innerHTML.replace(/\.$/, " lub ustawiłeś odpowiednią opcję w konfiguracji Salon25.");} );

    // setTimeout because of: http://wiki.greasespot.net/0.7.20080121.0_compatibility
    setTimeout(function() {
      s25.reorder_blogroll();
    }, 0);
  }

}

s25.after_s24_init_hooks = function () {
  $().ready( s25.init_after_s24 );
}

s25.persistent_login = function () {

  //if persistent login - change cookies to expiring instead of session ones
  if(s25.state.is_logged && (GM_getValue('persistent_login', false))) {
    var days = 7;
    var coo = [ 's_us_nick', 's_us_id', 'w_fpost', 'PHPSESSID', 'cq_cre', 'cq_chi', 'w_fnewspaper', 'w_fpost', 'w_fuser', 's_us_name' ];

    for(var c in coo)  {
      var key = coo[c];
      var val = $.cookie(key);
      if(val)
	$.cookie(key, val, { expires: days, path: '/', domain: s25.consts.domain } );
    }
  }

  //add login box checkbox to allow persistent login
  if($('form#service_login').length) {
    var perscb = s25.elem('input', { type: 'checkbox', id: 'persistent_login', checked: GM_getValue('persistent_login', 0)?'ckecked':null, style: { top: '1px', position: 'relative' } });
    s25.addEvent(perscb, 'change', function (e) { GM_setValue('persistent_login', this.checked); });
    var perslabel = s25.elem('label', { for: 'persistent_login', style: { cssFloat: 'none', display: 'inline', width: '100%', paddingLeft: '2px',  } }, [ "Nie wylogowywuj po wyjściu z przeglądarki" ]);
    var persdiv = s25.elem('p', {}, [ perscb, perslabel ]);
    $('form#service_login br.cb').before(persdiv);
  }



}


s25.update_filters = function () {

  hi = $('.cq_hi').addClass('cq_s25_hi');
  re = $('.cq_re').addClass('cq_s25_re');
  f1count = hi.size();
  f2count = re.size();
  hiddencount = f1count + (s25.get_filter(2) ? f2count : 0);

  if(GM_getValue('filter_highlight', true)) {
    hi.css('background-color', '#fffff0');
    re.css('background-color', '#fff0f0');
  }

  if(GM_getValue('filter_unlock', false)) {
    s25.change_filter(1, true); 
    if(s25.state.is_logged) s25.change_filter(2, true); 
  } else {
    s25.change_filter(1, s25.get_filter(1));
    s25.change_filter(2, s25.get_filter(2));
  }

  if(hiddencount) {
    if(GM_getValue('filter_unwrap_all', false))
      s25.unwrap_filtered(1|2);

    else {
      //pokaż link 'Rozwiń wszystkie komentarze' jeśli sa jakieś komentarze do rozwinięcia
      unlock_all = s25.createLink('#', 'Rozwiń');
      s25.addEvent(unlock_all, 'click', function(e) { s25.unwrap_filtered(1|2); $(this).parent().remove();e.preventDefault();});
      $('#comment-header').after(s25.elem('div', { style: {textAlign: 'right', padding: '0px 3px 5px 3px', borderBottom: '1px solid #d3d3d3', fontSize: 'smaller'}}, [unlock_all, ' wszystkie komentarze (' + hiddencount + ')'] ));
    }
  }
}


s25.apply_menu_look = function () {
  menu = document.getElementById('service-navi');
  if(!menu) return 1;

  hide_start = GM_getValue("titlebar_hide_start", false);
  hide_catalogs = GM_getValue("titlebar_hide_catalogs", false);
  shorten = GM_getValue("titlebar_shorten", false)

  dmn = s25.state.default_menu_names;

  for(i=0; i<menu.childNodes.length; i++) {
    if(!menu.childNodes[i].firstChild) continue;

    label = menu.childNodes[i].firstChild.innerHTML;
    el = menu.childNodes[i];
    id = el.id;

    if(id == 'service-navi-sg') el.style.display = hide_start ? 'none' : "";
    //if(id == 'service-navi-catalog') el.style.display = hide_catalogs ? 'none' : "";
    if(id == 'service-navi-blog-catalog') el.style.display = hide_catalogs ? 'none' : "";
    if(id == 'service-navi-np') el.style.display = hide_catalogs ? 'none' : "";
    if(id == 'service-navi-np-catalog') el.style.display = hide_catalogs ? 'none' : "";
    if(id == 'service-navi-myblog') el.style.borderLeft = hide_catalogs ? 'medium none' : "";
    if(id == 'service-navi-register') el.style.borderLeft = hide_catalogs ? 'medium none' : "";
    if(id == 'service-navi-sg') el.firstChild.innerHTML = shorten ? "SG" : dmn.servicenavisg;
    if(id == 'service-navi-manage') el.firstChild.innerHTML = shorten ? "Zarządzaj" : dmn.servicenavimanage;
    if(id == 'service-navi-disc') el.firstChild.innerHTML = shorten ? 'Dyskusje' : dmn.servicenavidisc;
    if(id == 'service-navi-catalog') el.firstChild.innerHTML = shorten ? 'Blogi' : dmn.servicenavicatalog;
    if(id == 'service-navi-blog-catalog') el.firstChild.innerHTML = shorten ? 'Blogi' : dmn.servicenaviblogcatalog;
    if(id == 'service-navi-np-catalog') el.firstChild.innerHTML = shorten ? 'Kat. lubczy' : dmn.servicenavinpcatalog;
  }
}

s25.update_menu = function () {

  menu = document.getElementById('service-navi');
  if(!menu) return 1;

  //zapamietaj domyślne nazwy w oryginalnym menu
  //znajdź "Logout" w menu i zapamiętaj
  for(i=0; i<menu.childNodes.length; i++) {
    if(!menu.childNodes[i].firstChild) continue;
    label = menu.childNodes[i].firstChild.innerHTML;
    el = menu.childNodes[i];
    id = el.id;

    eval("s25.state.default_menu_names." + id.replace(/-/g,'') + "=\"" + label + "\"");
    if(id == 'service-navi-logout') 
      menu_logout = el;
  }

  s25.apply_menu_look();


  //dodaj 'obserwowane' do menu
  if(s25.state.my_domain && menu_logout) {
    //delayed add to menu - otherwise endless loop in for
    watched = document.createElement('li');
    watched.style.display = 'list-item';
    s25.state.watched_link = s25.createLink(s25.consts.admin_url + 'posts-comments-watch/', 'Obserwowane');
    s25.state.watchedcount_link = s25.createLink(s25.consts.admin_url + 'posts-comments-watch/', '(0)');
    s25.state.watchedcount_link.style.display = 'none';
    s25.state.watchedcount_link.style.color='red';
    //jeśli nowy komentarz jest w tej samej notce i nie zmienia się URL, to trzeba odświeżyć stronę - inaczej ani komentarz nie będzie widoczny, ani nie zadziała #show-laet-
    s25.addEvent(s25.state.watchedcount_link, 'click', function(e) { if(this.href.split('#')[0] == document.location.href.split('#')[0]) { e.preventDefault(); document.location.href = this.href; document.location.reload(); }} );
    watched.appendChild(s25.state.watched_link);
    watched.appendChild(document.createTextNode(' '));
    watched.appendChild(s25.state.watchedcount_link);
    s25.update_ui_watched();

    s25.state.newmails_li = document.createElement('li');
    s25.state.newmails_li.style.display = 'list-item';
    link = s25.createLink(s25.consts.admin_url + 'mail/', 'nowa poczta');
    link.style.color = 'red';
    s25.state.newmails_li.appendChild(link);
    //przejmij obsługe informacji o nowej poczcie od skryptu salonowego (nasza lepsza - live update)
    unsafeWindow.Service.checkNewMailsShow = function () { if (this.checkNewMailsCnt){ if(!s25.state.newmails) s25.state.newmails = this.checkNewMailsCnt; s25.update_ui_newmails(); }};
    s25.update_ui_newmails();

    menu.insertBefore(s25.state.newmails_li, menu_logout);
    menu.insertBefore(watched, menu_logout);
  }
  

  if(GM_getValue("floating_top_menu",0)) {
    sh = document.getElementById('service-header');
    sh.style.position = 'fixed';
    
    sh.style.width = '810px';
    //sh.style.backgroundColor = 'black';
    
    bsh = document.createElement('div');
    bsh.style.position = 'fixed';
    bsh.style.width = '100%';
    bsh.style.height = '30px';
    bsh.style.left = '0px';
    bsh.style.backgroundColor = 'black';
    sh.parentNode.insertBefore(bsh,sh);

    bh = document.getElementById('blog-header');
    bh.style.paddingTop = '30px';
    
  }

}

s25.delete_comment = function (my, comment, link) {
  var id = s25.get_comment_id(comment);

  if(link.style.color!='red') {
    link.innerHTML = 'na pewno skasować?'; 
    link.style.color='red';
    return 0;
  }
 
  var url;
  if(my)
    url = s25.consts.admin_url + 'comments-my-delete-json/' +id;
  else
    url = s25.consts.admin_url + 'comments-delete-json/' + id;

  s25.loadPage(url,
      function (responseDetails) { 
	//s25.log('skasowano');
        link.innerHTML = 'skasowany';
	comment.style.display = 'none';
	return 0;
      },
      function (responseDetails) {
        link.innerHTML = 'nie udało się skasować';
	return 0;
      }
 );
}

s25.get_comment_id = function (comment) {
  for(f=0;f<comment.childNodes.length;f++) {
    field = comment.childNodes[f];
    if(field.nodeName == "A" && field.name) {
      commentname = field.name;
      u = commentname.indexOf('_');
      commentid = commentname.slice(u+1);
      break;
    }
  }
  return commentid;
}

s25.get_comment_form = function (id) {
  if(id)
    form = document.getElementById('comment_form-add_comment_form-' + id);
  else 
    form = document.getElementById('comment_form-add_comment_form');
  return form;
}

s25.get_comment_message = function (form,id) {
  if(!form) return null;
  ta = form.getElementsByTagName('textarea');
  for(input=null,i=0;i<ta.length;i++) {
    if(ta[i].name == 'message') {
      input = ta[i];
      break;
    }
  }
  return input;
}

s25.get_comment_title = function (form,id) {
  if(!form) return null;
  inputs = form.getElementsByTagName('input');
  for(i=0;i<inputs.length;i++) {
    if(inputs[i].name == 'title'){ 
      input = inputs[i];
      break;
    }
  }
  return input;
}

s25.insert_at_cursor = function (ta, val) { //thanks to Alex King - http://alexking.org/blog/2003/06/02/inserting-at-the-cursor-using-javascript
  if (ta.selectionStart || ta.selectionStart == '0') {
    var startPos = ta.selectionStart;
    var endPos = ta.selectionEnd;
    ta.value = ta.value.substring(0, startPos) + val + ta.value.substring(endPos, ta.value.length);
    ta.selectionStart = ta.selectionEnd = startPos + val.length;
  } else {
    ta.value = val + ta.value;
  }
}

s25.quote_comment = function (id) { 
  form = s25.get_comment_form(id);
  input = s25.get_comment_message(form, id);
  
  cid='comment-body-' + id;
  q=document.getElementById(cid).innerHTML; 
  if(q && q.length) 
    s25.insert_at_cursor(input, s25.consts.quote_start + q.replace(/<br>/g,'') + s25.consts.quote_end);
  input.focus();
}


s25.quote_sel = function (id) {
  form = s25.get_comment_form(id);
  input = s25.get_comment_message(form, id);
  if(!input) return;

  sel = window.getSelection().toString();
  if(sel.length) 
    s25.insert_at_cursor(input, s25.consts.quote_start + sel.replace(/&/g,'&amp;').replace(/>/g,'&gt;').replace(/</g,'&lt;') + s25.consts.quote_end);
  input.focus();
}

s25.preview_comment = function (id) {
  s25.log('s25.preview_comment ' + id);
  form = s25.get_comment_form(id);

  if(form.nextSibling && form.nextSibling.id=='comment-preview-' + id) {
    ct = document.getElementById('comment-preview-title-' + id);
    cb = document.getElementById('comment-preview-body-' + id);
  } else {

    //okno podglądu
    prwindow = document.createElement('div');
    prwindow.id = 'comment-preview-' + id;
    //prwindow.style.width = '470px';
    prwindow.style.width = '578px';
    prwindow.style.background  = '#eee';
    prwindow.style.marginLeft  = '-11px';
    prwindow.style.marginBottom  = '5px';
    prwindow.style.border = '1px solid #f55';
    //prwindow.style.display = 'none';

    ct = document.createElement('h3');
    ct.className = 'comment-title';
    ct.id = 'comment-preview-title-' + id;

    cb = document.createElement('p');
    cb.className = 'comment-body';
    cb.id = 'comment-preview-body-' + id;

    prwindow.appendChild(ct);
    prwindow.appendChild(cb);

    form.parentNode.appendChild(prwindow);
  }

  title = message = "";

  input = s25.get_comment_title(form, id);
  if(input) title = input.value;
  input = s25.get_comment_message(form, id);
  if(input) message = input.value;

  ct.innerHTML = title;
  cb.innerHTML = message.replace(/\n/g,'<br>');
}

s25.ev_quote_comment = function (e) {
  s25.quote_comment(parseInt(this.parentNode.id.slice(8)));
  e.preventDefault();
}

s25.ev_quote_sel = function (e) {
  s25.quote_sel(parseInt(this.parentNode.id.slice(8)));
  e.preventDefault();
}
s25.ev_preview_comment = function (e) {
  s25.preview_comment(parseInt(this.parentNode.id.slice(8)));
  e.preventDefault();
}




s25.update_comment = function (comment) {

  //'zablokuj' [komentatora] na obcych blogach
  isEditor = unsafeWindow.Service.newspaperEditors && unsafeWindow.Service.newspaperEditors.indexOf(parseInt($.cookie('s_us_id'))) >= 0;
  //if(comment.script_tag && comment.author_id && s25.state.blog_domain != s25.state.my_domain && !isEditor) {
  //nie dodajemy 'zablokuj' w LC, bo nie możeemy w cudzych blokować a w swoich 'zblokuj' jest
  if(comment.script_tag && comment.author_id && s25.state.blog_domain != s25.state.my_domain && !unsafeWindow.Service.newspaperUrl) {
    alock = s25.createLink('#lock-user-' + comment.author_id, 'zablokuj');
    alock.title = 'dodaj do listy zablokowanych użytkowników';
    alock.setAttribute('user_to_lock', comment.author_id);
    s25.addEvent(alock, 'click', function(e) { /* id = parseInt(this.href.slice(this.href.indexOf('#')+11))); */ id=this.getAttribute('user_to_lock'); unsafeWindow.Service.lockUserPopup(id); e.preventDefault(); } );
    spanlock = document.createElement('span');
    spanlock.className = 'le';
    spanlock.appendChild(alock);
    comment.script_tag.parentNode.insertBefore(spanlock, comment.script_tag);
  }

  //'mailto'
  if(comment.nick_tag && comment.author_id) {
    //dodaj ikonkę 'wyslij wiadomość'
    mailto = s25.createLink(s25.consts.admin_goto_url + 'mail-new/' + comment.author_id, ' ');
    mailto.title = 'wyślij wiadomość do autora komentarza';
    mailto.style.backgroundImage = 'url(http://s.' + s25.domain + '/admin/gfx/icons.gif)';
    mailto.style.backgroundPosition = '4px -87px';
    mailto.style.backgroundRepeat = 'no-repeat';
    mailto.style.paddingLeft = '20px';
    
    span = document.createElement('span');
    span.className = 'le';
    span.appendChild(document.createTextNode('|'));
    span.appendChild(mailto);
    span.appendChild(document.createTextNode('|'));


    comment_date = comment.nick_tag.firstChild;
    while(comment_date && (comment_date.nodeType != 1 || comment_date.className!='le comment-date')) comment_date = comment_date.nextSibling; //firefox 3.0 nie ma firstElementChild
    comment.nick_tag.insertBefore(span,comment_date.nextSibling);
  }

  if(comment.navi_tag) {

    if(0) {
      clink = canswer = null;
      for(n=0;n<comment.navi_tag.childNodes.length;n++) {
	switch(comment.navi_tag.childNodes[n].innerHTML) {
	  case 'link do komentarza': clink = comment.navi_tag.childNodes[n]; break;
	  case 'odpowiedz': canswer = comment.navi_tag.childNodes[n]; break;
	}
      }
    } else {
      clink = comment.navi_tag.firstChild;
      while(clink && clink.nodeType != 1) clink = clink.nextSibling; //firefox 3.0 nie ma firstElementChild
      canswer = comment.navi_tag.lastChild;
      while(canswer && canswer.nodeType != 1) canswer = canswer.previousSibling; //firefox 3.0 nie ma lastElementChild
    }

    //podmień obsługę 'odpowiedz' na własną
    if(canswer) {
      comment.comment_text_tag.id = 'comment-body-' + comment.commentid;
      canswer.setAttribute('commentid', comment.commentid);
      canswer.setAttribute('author_nick', comment.author_nick);
    }

  }
}

s25.comment_add_buttons = function (id, postbuttons) {
  if(id) {
    //cytuj komentarz
    quote = s25.createLink('#', 'cytuj komentarz');
    quote.style.marginRight='1em';
    //quote.style.display = 'none';
    quote.id = 'quote-comment-button';
    quote.className = 'button_cancel';
    s25.addEvent(quote, 'click', s25.ev_quote_comment);
  }

  //cytuj zaznaczenie
  quotesel = s25.createLink('#', 'cytuj zaznaczenie');
  quotesel.style.marginRight='1em';
  quotesel.className = 'button_cancel';
  s25.addEvent(quotesel, 'click', s25.ev_quote_sel);

  //podgląd
  preview = s25.createLink('#', 'podgląd');
  preview.style.marginRight='1em';
  preview.className = 'button_cancel';
  s25.addEvent(preview, 'click', s25.ev_preview_comment);

  postbuttons.insertBefore(preview,postbuttons.firstChild);
  postbuttons.insertBefore(quotesel,postbuttons.firstChild);
  if(id) postbuttons.insertBefore(quote,postbuttons.firstChild);
}



s25.patched_addComment = function (_selector, _item_oid, _default_title) {

  //addComent is also called on 'abort comment. No special processing then
  if (!$(_selector).is(':hidden') && $(_selector).html())
    return orig_addComment(_selector, _item_oid, _default_title);

  if(_selector == '#add_comment_form')
    id = 0;
  else 
    id = parseInt(_selector.split('-')[1]);
  s25.log('s25.patched_addComment ' + id);


  var onick;
  if(_default_title)
    onick = _default_title.replace(/^@/,'');
  else if(typeof(s25.state.blog_author_name) != 'undefined') {
    onick = s25.state.blog_author_name;
    _default_title = '@' + onick;
  }

  if(s25.state.comment_template)
    _default_title = s25.state.comment_template_title.replace(/\$NICK/g,onick);

  ret = orig_addComment(_selector, _item_oid, _default_title);

  var ta = $(_selector).find('textarea')[0];
  var cm = $(_selector).find('input[name*="title"]')[0];

  if(ta && s25.state.comment_template) {
    var v = s25.state.comment_template_content.replace(/\$NICK/g,onick);
    var cursor = v.indexOf('$CURSOR');
    v = v.replace(/\$CURSOR/g, "");
    ta.value = v;
    if(cursor != -1)
      $(_selector).queue( function () { ta.selectionStart = ta.selectionEnd = cursor;     $(this).dequeue(); $(this).clearQueue(); });
  }
  $(_selector).queue( function () { if(_default_title) ta.focus(); else cm.focus();  $(this).dequeue(); $(this).clearQueue(); });
  
  form = s25.get_comment_form(id);
  p = form.getElementsByTagName('p');
  for(buttons = null,ip=0;ip<p.length;ip++){
    if(p[ip].className=='buttons')
      buttons = p[ip];
  }
  if(!buttons) return ret;

  buttons.id = 'buttons-' + id;
  s25.comment_add_buttons(id, buttons);

  return ret;
}


s25.add_buttons = function () {
  orig_addComment = unsafeWindow.Service.addComment;
  unsafeWindow.Service.addComment = s25.patched_addComment;
}



s25.update_comments = function () {
  
  //extend_comment_form();
  s25.add_buttons();

  cinfo = s25.parse_comments();
  if(!cinfo) return -1;

  for(c=0;c<cinfo.length;c++)
    s25.update_comment(cinfo[c]);

  s25.update_comments_jumpto(cinfo);

  post_comment = s25.getElementByClass('ico_write_comm', document, 'a');
  if(post_comment)
    post_comment.setAttribute('onclick', post_comment.getAttribute('onclick').replace(/(\);return false;)/, ', "@' + s25.state.blog_author_name + '"$1'));
 
  return 0;
}

s25.parse_comments = function () {

  var cinfo = new Array();
  var comments = $('ul.comments-list>li.comment');
  var comment_no;

  for(comment_no=0,child=0;child<comments.length;child++) {

    cinfo[comment_no] = new Object();

    var comment = cinfo[comment_no];
    comment.li = comments[child];

    //s25.log('next comment have ' + comments[child].childNodes.length + ' fields');
    for(f=0;f<comments[child].childNodes.length;f++) {
      field = comments[child].childNodes[f];
      //s25.log('name ' + field.nodeName);
      if(field.nodeName == "A" && field.name) {
	comment.commentname = field.name;
	var u = comment.commentname.indexOf('_');
	comment.commentid = comment.commentname.slice(u+1);
	//s25.log('comment ' + comment.commentname + ' id ' + comment.commentid);

      }
      if(field.className=='author') {
	//comment.nick_tag = s25.getElementByClass('author-nick', field); 
	//speedup
	comment.nick_tag = field.firstChild;
	while(comment.nick_tag && comment.nick_tag.nodeType != 1) comment.nick_tag = comment.nick_tag.nextSibling; //firefox 3.0 nie ma firstElementChild
	if(comment.nick_tag.nodeName == 'IMG') {
	  comment.nick_tag = comment.nick_tag.nextSibling;
	  while(comment.nick_tag && comment.nick_tag.nodeType != 1) comment.nick_tag = comment.nick_tag.nextSibling; //firefox 3.0 nie ma nextElementSibling
	}
	comment.author_domain = comment.nick_tag.host;
	comment.author_nick = comment.nick_tag.innerHTML;

	comment.script_tag = field.getElementsByTagName('script')[0];
	//comment.author_id = parseInt(comment.script_tag.innerHTML.slice(21,-2));
	comment.author_id = parseInt(comment.script_tag.innerHTML.replace(/.*\(([0-9]*)\);/,'$1'));
      }

      if(field.className=='comment-body')
	comment.comment_text_tag = field;

      if(field.className=='comment-navi')
	comment.navi_tag = field;

    }
    comment_no++;
  }

  return cinfo;
}

//process jump to comment directive (#show-last-n)
s25.update_comments_jumpto = function (cinfo) {
  if(!cinfo.length) {
    //GM_log("No comments available");
    return;
  }

  if(document.location.hash.indexOf(s25.consts.show_last_hash) != 0)
    return;
  
  //s25.log(document.location.hash);
  jumpto = cinfo.length - parseInt(document.location.hash.slice(s25.consts.show_last_hash.length));
  
  //document.location.hash = cinfo[jumpto].commentname;
  //s25.log(document.location.href.split('#')[0] + '#' +  cinfo[jumpto].commentname);
  document.location.replace(document.location.href.split('#')[0] + '#' +  cinfo[jumpto].commentname);
}

s25.update_footer = function () {
  footerlinks = document.getElementById('footer-links');
  if(footerlinks) {
    //about = s25.createLink(s25.consts.project_url, s25.meta.name);
    about = s25.createLink(s25.consts.admin_url + '#salon25', s25.meta.name);
    about.title = s25.meta.name + ', ver. ' + s25.meta.version + ' - konfiguracja';
    about.style.color = 'red';
    footerlinks.appendChild(document.createTextNode(" |\u00a0 "));
    footerlinks.appendChild(about);

    footerlinks.style.width='550px';
  }
}


s25.event_add_fav_post = function (postid) {
  //s25.log('GM_xmlhttpRequest(' + address + ')');
  address = 'http://' + s25.state.blog_domain + '/favorite-post-add/';
  data = 'post_oid=' + postid;

  /*
  if(s25.state.add_to_fav) {
    s25.state.add_to_fav.style.backgroundImage = 'url(' + s25.media.throbbericon + ')';
    s25.state.add_to_fav.style.backgroundRepeat = 'no-repeat';
    s25.state.add_to_fav.style.paddingLeft = '16px';
    s25.state.add_to_fav.style.backgroundPosition = 'left 3px';
  }
  */

  s25.postPage(address, data, s25.lp_add_fav_post_ok, s25.lp_add_fav_post_err);
}

s25.lp_add_fav_post_ok = function (responseDetails) {
  s25.log(responseDetails.responseHeaders);
  s25.add_fav_post_done(responseDetails.finalUrl.slice(-5) != '/404/');
}

s25.lp_add_fav_post_err = function (responseDetails) {
  s25.log(responseDetails.responseHeaders);
  s25.add_fav_post_done(false);
}

s25.add_fav_post_done = function (success) {
  if(s25.state.add_to_fav) {
    if(success) {
      s25.state.add_to_fav.style.color = 'green';
      s25.state.add_to_fav.innerHTML = 'dodany do obserwowanych';
    }
    else {
      s25.state.add_to_fav.style.color = 'red';
      s25.state.add_to_fav.innerHTML = 'nie udane dodanie do obserwowanych';
    }
  }
}


s25.update_tag_page = function () {
  if(document.location.pathname.slice(0,5) == '/tag/') {
    tag = document.getElementsByTagName('h1')[0];
    h3 = document.getElementsByTagName('h3')[0];
    if(h3.innerHTML == 'moje tagi') {
      link = document.createElement('a');
      link.href=document.location.href.replace(new RegExp('//.*\.(' + s25.domain + '/.*)'),'//www.$1');
      link.innerHTML = "tag \"" + tag.innerHTML + "\" w całym serwisie &raquo;";
      h3.parentNode.insertBefore(link,h3.nextSibling.nextSibling.nextSibling);
    }
  }
}

s25.postPage = function (address, data, onLoad, onError) {
  //s25.log('GM_xmlhttpRequest(' + address + ')');
  GM_xmlhttpRequest({
    method: 'POST',
    url: address,
    data : data,
    headers: {
      'Cookie': document.cookie,
      //'Accept-Charset': 'ISO-8859-2',
//      'X-Requested-With': 'XMLHttpRequest',
      'Content-type' : 'application/x-www-form-urlencoded',
    },
    onload: function(responseDetails) {
      //s25.log('status:' + responseDetails.status);
      //s25.log('finalUrl: '+responseDetails.finalUrl);
      if(responseDetails.status != 200) {
	//hideLoadingInfo();
	s25.log('status: ' + responseDetails.status);
	s25.log('statustext:\n'+responseDetails.statusText);
	s25.log('responsetext:\n'+responseDetails.responseText);
	return;
      }	

      if(onLoad) onLoad(responseDetails);
    },

    onerror: function(responseDetails) {
      s25.log('status:\n' + responseDetails.status);
      s25.log('statustext:\n'+responseDetails.statusText);
      s25.log('responsetext:\n'+responseDetails.responseText);
      //hideLoadingInfo();
      if(onError) onError(responseDetails);
    }
  });
}

s25.update_div = function (nver) {

  div = document.createElement('div');
  div.id = 'verupdate';
  ln1 = document.createElement('span');
  ln1.style.fontWeight='bold';
  ln1.appendChild(document.createTextNode('Uwaga, pojawiła się nowsza wesja skryptu Salon25'));
  ln1.appendChild(document.createElement('br'));
  ln2 = document.createElement('span');
  ln2.appendChild(document.createTextNode('Aktualnie używasz wersji: ' + s25.meta.version + ', a najnowasza wersja to ' + nver));
  ln2.appendChild(document.createElement('br'));
  ln2.appendChild(document.createElement('br'));
  ln3 = document.createElement('span');
  ln3.appendChild(document.createElement('br'));
  ln3.appendChild(document.createTextNode('Zobacz '));
  ln3.appendChild(s25.createLink(s25.consts.project_url, 'stronę projektu Salon25'));
  ln3.appendChild(document.createTextNode(' żeby zobaczyć co się zmieniło.'));
  ln3.appendChild(document.createElement('br'));
  ln3.appendChild(document.createElement('br'));
  ln4 = document.createElement('span');
  if(s25.state.is_ff_extension)
    ln4.appendChild(s25.createLink('http://dl.dropbox.com/u/15707854/salon25.xpi', 'Zaktualizuj do najnowszej wersji'));
  else
    ln4.appendChild(s25.createLink('http://salon25.googlecode.com/svn/tags/v' + nver + '/salon25.user.js', 'Zaktualizuj do najnowszej wersji'));
  ln4.appendChild(document.createElement('br'));
  ln5 = document.createElement('div');
  ln5.style.textAlign = 'right';
  link = s25.createLink('#', 'Zamknij okno');
  s25.addEvent(link, 'click', function(e) { document.getElementById("verupdate").style.display="none"; e.preventDefault(); } );
  ln5.appendChild(link);
  ln5.appendChild(document.createElement('br'));

  div.appendChild(ln1);
  div.appendChild(ln2);
  div.appendChild(ln4);
  div.appendChild(ln3);
  div.appendChild(ln5);

  div.style.position = 'fixed';
  div.style.padding = '1em';
  div.style.backgroundColor = '#ffcccc';
  div.style.border = '2px solid red';
  div.style.top = '2em';
  div.style.left = '2em';

  document.getElementsByTagName('body')[0].appendChild(div);
}

s25.versionToInt = function (ver) {
  a = ver.split('.');
  return a[0] * 1000000 + a[1] * 1000 + a[2] * 1;
}

s25.onload_version_check_notify = function (responseDetails) {
  nver = responseDetails.responseText;
  GM_log("Current version is: " + s25.meta.version + " (" + s25.versionToInt(s25.meta.version) + ")");
  GM_log("Newest version is: " + nver + " (" + s25.versionToInt(nver) + ")");
  if(s25.versionToInt(nver) > s25.versionToInt(s25.meta.version))
    s25.update_div(nver);
}

s25.check_updates = function (force_check, action) {
  
  d=new Date();
  now = d.getTime();
  
  if(force_check)
    check = true;
  else {
    if(!GM_getValue('version_check_enabled', true))
      return;
    period = GM_getValue("version_check_delay", -1); //delay between checks (in seconds)
    if(period == -1) {
      period = 24 * 3600;
      GM_setValue("version_check_delay", period);
    }
    last = parseInt(GM_getValue("version_check_last", "0"));
    
    check = (last + period*1000) < now;
    //GM_log('previous check was at ' + ((now - last)/3600000) + ' hours ago; check = ' + check);
  }
  

  //GM_log('check ' + last + ' + ' + period + ' * 1000 - ' + now + ' = ' + (last + period*1000 - now));
  if(check) {
    GM_log('checking version update');
    GM_setValue('version_check_last', now.toString());

    s25.loadPage(s25.consts.version_check_url, action);
  }

}

s25.change_yesno = function (link, e) { 
  e.preventDefault(); 
  variable=link.getAttribute('variable'); 
  config_name=link.getAttribute('config_name'); 

  if(link.innerHTML == "ON" || link.innerHTML=='TAK')
    oldval = 1;
  else
    oldval = 0;

  //GM_log('change: was ' + oldval);

  val = !oldval;

  //GM_log('change: new ' + val);


  //GM_log('change: onchange new ' + val);

  if(val == oldval)
    return;

  link.innerHTML = val?"TAK":"NIE";

  if(variable != null)
    eval(variable + ' = ' + val + ';');
  if(config_name)
    GM_setValue(config_name, val);

  //GM_log('change: variable ' + variable + ' config_name ' + config_name);
  if(config_name)
    ;//GM_log(config_name + 'is ' + GM_getValue(config_name, 'unknown'));
  return val;

} 

s25.event_change_yesno = function (e) {
  s25.change_yesno(this, e);
  return false;
}


s25.unwrap_filtered = function (num) {
  if(num & 1) {
    $('.cq_s25_hi').each(function(l,el) { $(el).removeClass('cq_hi').addClass('cq_hi_acc'); if($(el).next().hasClass('cq_info')) $(el).next().remove();});
  }
  if(s25.get_filter(2) && num & 2) {
    $('.cq_s25_re').each(function(l,el) { $(el).removeClass('cq_re').removeClass('cq_hi').addClass('cq_hi_acc'); if($(el).next().hasClass('cq_info')) $(el).next().remove();});
  }
}




s25.change_filter = function (num, on) {

  cname = (num!=2) ? 'cq_chi' : 'cq_cre';

  if(on==true)
    ck = cname + '=' + '1' + '; path=/' + '; domain=.' + s25.domain;
  else {
    ck = cname + '=' + '1; path=/' + '; domain=.' + s25.domain + '; max-age=0' + '; expires=' + d.toGMTString();//Thu, 01-Jan-70 00:00:01 GMT;';
  }

  document.cookie = ck;

  //hack to allow open filter 2 for anybody logged or not
  if(num==2) unsafeWindow.CQ._u_acc_re = on;
  
  return on==true;
}

s25.get_cookies_array = function () {
  var cookies = document.cookie.split(' ');

  for(c=0;c<cookies.length;c++) {
    arr[c] = cookies[c].replace(/;$/,'').split('=');
  }
  return arr;
}

s25.get_filter = function (num) {
  var cookies = document.cookie.split(' ');

  cname = (num!=2) ? 'cq_chi' : 'cq_cre';

  for(c=0;c<cookies.length;c++) {
    cookies[c] = cookies[c].replace(/;$/,'');
  }

  for(c=0;c<cookies.length;c++) {
    cookie = cookies[c].split('=');
    if(cookie[0] == cname)
      return cookie[1]=='1';
  }
}

s25.ev_update_menu = function (e) { 
  s25.change_yesno(this, e);
  s25.apply_menu_look();
  return true;
}

s25.ev_change_filter1 = function (e) { 
  on = s25.change_yesno(this, e);
  s25.change_filter(1, on); 
  return true;
}

s25.ev_change_filter2 = function (e) { 
  on = s25.change_yesno(this, e);
  s25.change_filter(2, on); 
  return true;
}

/* Functions adds one On/Off setting to the menu and attaches handlers when the stat changes
 * 
 * variable - variable name (passed as string) connected to the setting
 * config_name - persistent (GM) setting name connected to the setting
 * onchange - callback function called with an event handler when state was changed
 *            should call s25.change_yesno(this, event) first and use return value as the actual value
 * one of three above should be set, remaining can be null (but all not-null will be processed)
 * defaultval - default value used if neither 'variable' nor 'config_name' returned any
 */
s25.menu_yesno_add = function (menu, mtitle, variable, config_name, onchange, defaultval) {

  tr= document.createElement('tr');
  title = document.createElement('td');
  value  = document.createElement('td');
  avalue = document.createElement('a');
  avalue.style.cursor = 'pointer';

  title.innerHTML = mtitle;

  if(variable!=null) 
    val = eval(variable);
  else if(config_name)
    val = GM_getValue(config_name, defaultval);
  else 
    val = defaultval;

  avalue.innerHTML = (val==1) ? 'TAK' : 'NIE';

  if(variable!=null)    avalue.setAttribute('variable', variable);
  if(config_name!=null) avalue.setAttribute('config_name', config_name);

  if(onchange!=null)
    s25.addEvent(avalue, 'click', onchange);
  else
    s25.addEvent(avalue, 'click', s25.event_change_yesno);


  title.style.width='250px';
  value.style.width='70px';
  tr.appendChild(title);
  value.appendChild(avalue);
  tr.appendChild(value);

  menu.appendChild(tr);

}

s25.menu_ro_add = function (menu, mtitle, mvalue) {

  tr= document.createElement('tr');
  title = document.createElement('td');
  value  = document.createElement('td');

  title.innerHTML = mtitle;
  value.innerHTML = mvalue;
  value.style.color = '#666';

  title.style.width='250px';
  value.style.width='70px';
  tr.appendChild(title);
  tr.appendChild(value);

  menu.appendChild(tr);

}

s25.menu_section = function (menu, mtitle) {
  tr= document.createElement('tr');
  title = document.createElement('th');
  title.innerHTML = mtitle;
  title.style.width='1000%';
  title.style.backgroundColor = '#ddd';
  title.style.border = '0px';
  title.style.borderBottom = '1px solid black';
  title.colSpan=2;
  tr.appendChild(title);
  menu.appendChild(tr);
}

s25.ev_reset_settings = function (e) {
  on = s25.change_yesno(this, e);
  if(on) {
    var keys = GM_listValues();
    for (var i=0, key=null; key=keys[i]; i++) {
      GM_deleteValue(key);
    }
    document.location.reload();
  }
}


s25.ev_comment_template = function (e) {
  on = s25.change_yesno(this, e);
  if(on)
    $('div#comment-template').show('slow');
  else
    $('div#comment-template').hide('slow');
}
     
s25.options_comment_template = function (where) {

  var itit=s25.elem('input', {style: {width: '100%'}, maxwidth: '128', id: 'comment-template-title', value: GM_getValue('comment_template_title', '')});
  s25.addEvent(itit, 'change', function (e) { GM_setValue('comment_template_title', this.value); });
  var icont=s25.elem('textarea', {style: { width: '100%', height: '200px'}, id: 'comment-template-content', value: GM_getValue('comment_template_content', '')});
  s25.addEvent(icont, 'change', function (e) { GM_setValue('comment_template_content', this.value); });

  var template = s25.elem('div', {style: {width: '100%', padding: '10px', border: '1px solid gray'}}, ['Szablon tytułu komentarza (możesz używać zmienniej $NICK):',s25.elem('br'),itit,s25.elem('br'),'Szablon treści komentarza (możesz używać zmiennych $NICK i $CURSOR):',s25.elem('br'),icont]);

  var div = s25.elem('div', {id: 'comment-template', style: { display: 'none'}}, [s25.elem('h3',{style:{marginTop: '1em'}},['Szablon komentarza']), template]);

  if(GM_getValue('comment_template', false))
    $(div).show();

  where.appendChild(div);

}


s25.options_add_menu = function (where, showadvanced) {
  var adv = showadvanced || GM_getValue('menu_advanced', false);
  menu = document.createElement('div');
  menu.style.width='320px';
  menu.style.backgroundColor = '#eee';

  table = document.createElement('table');
  table.style.width='100%';

  s25.menu_section(table, 'Filtry');
  s25.menu_yesno_add(table, 'Odblokuj filtr 1', null, null, s25.ev_change_filter1, s25.get_filter(1));
  if(adv || s25.state.is_logged) s25.menu_yesno_add(table, 'Odblokuj filtr 2', null, null, s25.ev_change_filter2, s25.get_filter(2));
  s25.menu_yesno_add(table, 'Oznaczaj zafiltrowane treści', null, "filter_highlight", null, 1);
  s25.menu_yesno_add(table, 'Automatycznie odblokuj filtry', null, "filter_unlock", null, 0);
  s25.menu_yesno_add(table, 'Automatycznie rozwijaj komentarze', null, "filter_unwrap_all", null, 0);
  s25.menu_section(table, 'Górne menu');
  s25.menu_yesno_add(table, 'Skróć nazwy linków', null, "titlebar_shorten", s25.ev_update_menu, 0);
  s25.menu_yesno_add(table, 'Ukryj link "Start"', null, "titlebar_hide_start", s25.ev_update_menu, 0);
  s25.menu_yesno_add(table, 'Ukryj katalog blogów i lubczasopism', null, "titlebar_hide_catalogs", s25.ev_update_menu, 0);
  s25.menu_section(table, 'Strona Główna');
  s25.menu_yesno_add(table, 'Popraw linki do LC na Stronie Głównej', null, "sg_fix_lc", null, 1);
  s25.menu_yesno_add(table, 'Normalizuj Aktywne Dyskusje', null, "ad_normalize", null, 1);
  s25.menu_yesno_add(table, 'Lewa kolumna SG jako menu rozwijalne', null, "left_column_menu", null, 0);
  s25.menu_yesno_add(table, 'Pomniejsz tytuły notek', null, "sg_fix_fontsize", null, 1);
  s25.menu_yesno_add(table, 'Ukryj chmurkę Facebooka', null, "sg_hide_fb", null, 0);
  s25.menu_section(table, 'Blogi i komentarze');
  s25.menu_yesno_add(table, 'Zmieniaj kolejność w profilu bloga', null, "blogroll_reorder", null, 0);
  if(adv) {
    //s25.menu_section(table, 'Komentarze');
    s25.menu_yesno_add(table, 'Szablon komentarza', null, "comment_template", s25.ev_comment_template, 0);
  }
  s25.menu_section(table, 'Inne');
  s25.menu_yesno_add(table, 'Obserwowane w lewym dolnym rogu', null, "bottom_notification", null, 0);
  s25.menu_yesno_add(table, 'Nie wylogowywuj po wyjściu z przeglądarki', null, "persistent_login", null, 0);
  s25.menu_section(table, 'Konfiguracja');
  s25.menu_yesno_add(table, 'Zresetuj konfigurację', null, null, s25.ev_reset_settings, 0);
  s25.menu_yesno_add(table, 'Debug', null, "debug", null, 0);
  if(adv) {
    s25.menu_yesno_add(table, 'Sprawdzaj aktualizacje Salon25', null, "version_check_enabled", null, 1);
    s25.menu_ro_add(table, 'Sprawdzaj co', GM_getValue('version_check_delay', '?')/3600 + 'h');
    s25.menu_section(table, 'Zaawansowane');
    s25.menu_yesno_add(table, 'Pokaż zaawansowane', null, "menu_advanced", null, 0);
  }

  menu.appendChild(table);
 

  where.appendChild(menu);

  s25.options_comment_template(where);

}

s25.onload_version_check_options_update = function (responseDetails) {
  nver = responseDetails.responseText;

  span = document.getElementById('options-ver');
  if(!span) return;

  text = document.createTextNode('Najnowsza dostępna wersja to ' + nver + ' ');
  span.replaceChild(text, span.firstChild);
  if(s25.versionToInt(nver) > s25.versionToInt(s25.meta.version)) {
    if(s25.state.is_ff_extension)
      a = s25.createLink('http://dl.dropbox.com/u/15707854/salon25.xpi', '[ZAINSTALUJ]');
    else
      a = s25.createLink('http://salon25.googlecode.com/svn/tags/v' + nver + '/salon25.user.js', '[ZAINSTALUJ]');
    a.style.color = 'blue';
    span.style.color = 'red';
    span.appendChild(a);
  }
  else
    span.style.color = 'green';
}


s25.options_add_footer = function (where) {
  div = document.createElement('div');
  div.style.color = 'gray';
  div.style.marginTop = '3em';
  div.appendChild(document.createTextNode('nowości odnośnie projektu w lubczasopiśmie: '));
  div.appendChild(s25.createLink('http://lubczasopismo.' + s25.domain + '/extensions/', 'Dodatki dla salonu24'));
  div.appendChild(document.createElement('br'));
  div.appendChild(document.createTextNode('strona projektu: '));
  div.appendChild(s25.createLink(s25.consts.project_url, s25.consts.project_url));
  div.appendChild(document.createElement('br'));
  div.appendChild(document.createTextNode('kontakt z autorami: '));
  div.appendChild(s25.elem('span', {style: {color: 'black'}}, ['Jan Słupski (', s25.createLink('http://follow.' + s25.domain + '/','follow'), ') & ', s25.createLink('http://greasemonkey.' + s25.domain + '/', 'greasemonkey')]));
  where.appendChild(div);
}

s25.options_add_lead = function (where) {

  div = document.createElement('div');
  div.appendChild(document.createTextNode('wersja ' + s25.meta.version));
  div.appendChild(document.createElement('br'));
  span = document.createElement('span');
  span.id = 'options-ver';
  a = s25.createLink(s25.consts.version_check_url, 'sprawdź czy dostępna jest nowsza wersja &rarr; ');
  a.style.cursor = 'pointer';
  a.style.color = 'gray';
  s25.addEvent(a, 'click', function (e) { e.preventDefault(); this.innerHTML = 'sprawdzam'; s25.check_updates(true, s25.onload_version_check_options_update); } );
  span.appendChild(a);
  div.appendChild(span);

  where.appendChild(div);
  where.appendChild(document.createElement('br'));

}

s25.ev_show_options_page = function (e) {
  e.preventDefault(); 
  document.location.hash = '#salon25';

  s25.state.advanced_menu_magic++;

  s25.show_options_page();
}

s25.show_options_page = function () {
  var area = $('#content .content-left')[0];
  if(s25.undef(area)) area = $('#content .content-full')[0];
  if(s25.undef(area)) return;

  var narea = s25.elem('div', {id: 'salon25-config', className:'content-left'}, [s25.elem('h1', {innerHtml:'Salon25'})]);

  s25.options_add_lead(narea);
  s25.options_add_menu(narea, s25.state.advanced_menu_magic>=10);
  s25.options_add_footer(narea);
 
  $(area).replaceWith(narea);

  $("a[href='http:///']").attr('href','#');
}


s25.options_page = function () {
  if(document.location.href.slice(0,s25.consts.admin_url.length) == s25.consts.admin_url && document.location.hash == '#salon25') {
    s25.show_options_page();
  }

  s25.options_page_toolbar_entry();
}


s25.options_page_toolbar_entry = function () {

  if(document.location.href.slice(0,s25.consts.admin_url.length) != s25.consts.admin_url)
    return;

  nav=document.getElementById('navigation');
  if(!nav) return;


  konfig_a = s25.createLink('/settings-account/#salon25', 'Konfiguracja', {style: {cursor: 'pointer'}});
  s25.addEvent(konfig_a, 'click', s25.ev_show_options_page);
  konfiguracja = s25.elem('li', null, [konfig_a]);

  listaopcji = [konfiguracja];

  menu_s25_a = s25.createLink('/settings-account/#salon25', 'Salon25', {className: 'head', id: 's25menu'});
  menu_s25 = s25.elem('li', null, [menu_s25_a, s25.elem('ul', {style: {display: 'block'}}, listaopcji)]);

  nav.appendChild(menu_s25);

  
}


s25.update_discussions = function () {
  if(!URL.matches('http://www.' + s25.domain + '/discussions/$')) return;

  if(GM_getValue('ad_normalize', true)) {
    $('.sg-left .post-list li').each(function() {
      var old_l = $(this).find('h3 a')[0];
      $(old_l).replaceWith(s25.elem('a', {href:old_l.href, innerHTML:old_l.innerHTML.ssplit(":", 1)[1]}));
      $(this).find('p:first').remove().insertAfter($(this).find('h3:first').css({'padding-bottom':'10px'}));
      $(s25.elem('a',{href : old_l.href.split("/",3).join('/'),
                           innerHTML : old_l.innerHTML.split(":",1)[0],
                           className : 'le'
                          })).insertBefore($(this).find('.author-about-body span:first'));

      $(s25.elem('span', {innerHTML:'&nbsp;|&nbsp;', className:'le'})).insertBefore($(this).find('.author-about-body span:first'));
    });
  }
  $('.sg-left .post-list h3 a').css({'font-size':'1em'});

  if(GM_getValue('left_column_menu', false)) s25.create_drop_menu();
}

s25.update_main_page = function () {
  if(gvar.isBuggedChrome) return; //sadly
  if(!URL.matches('http://www.' + s25.domain + '/$')) return;

  if(GM_getValue('sg_fix_lc', true)) {

    $('.sg-left .post-list li').each(function() {
      var link = $(this).find('h3 a')[0];
      if(typeof(a)=='undefined') return;

      var author = $(this).find('.author a:first').attr('href');
      link.href = author + link.href.split("/")[link.href.split("/").length-1];
      link.href = link.href.replace(/news-list/, 'news');
    });
  }

  if(GM_getValue('sg_fix_fontsize', true)) $('.sg-left .post-list h3 a').css({'font-size':'1em'});

  if(GM_getValue('left_column_menu', false)) s25.create_drop_menu();
  
  if(GM_getValue('ad_next_to_latest', false)) s25.create_ad_column();

  if(GM_getValue('sg_hide_fb', false)) $('#FB-stick').hide();


      
}

s25.create_ad_column = function () {
  $('.sg-right').css({'width':'200px'});
  $('#service-last-posts').css({'display':'inline'});

  s25.loadPage('http://www.' + s25.domain + '/discussions/', s25.get_active_discussions);
}

s25.create_drop_menu = function () {
  $('.content-left-navi').hide().hover(function() {
         $(this).show();
      },
      function() {
         $(this).hide();
      }).css({'position':'absolute', 'zIndex':1000});

  $('#sg-right-wrapper').css({'width':'990px'});

  $('#service-navi').before(s25.elem('a', {innerHTML:'Nawigacja',
                                        id : 'custom-nav-link',
                                        style: {color:'#999999', 
                                             backgroundColor:'#383838', 
                                             marginTop:'35px', 
                                             marginLeft:'10px', 
                                             position:'absolute',
                                             border:'medium none',
                                             borderTopLeftRadius:'4px',
                                             borderTopRightRadius:'4px',
                                             lineHeight:'24px',
                                             paddingLeft:'5px',
                                             paddingRight:'5px'
                                             }
                                        }));
  $('#custom-nav-link').hover(function() {
         $('.content-left-navi').show();
      },
      function() {
         $('.content-left-navi').hide();
      });
  $('.sg-left').css('width', '680px');
}

s25.create_blog_lc_links = function (a) {
  var link = a.href;
  var direct_link = s25.elem('a', {href : '#', innerHTML : a.innerHTML});
  var article_link = link.split("/")[link.split("/").length-1];

  s25.addEvent(direct_link, 'click', 
      function(e) { 
          s25.loadPage(link, function(response) { location.href = s25.get_author(response).blog + article_link; });
          e.preventDefault();
          return false;
      } 
  );

  s25.addEvent(direct_link, 'mouseover', 
      function(e) { 
          s25.loadPage(link, 
            function(response) { 
                if(direct_link.href != 'http://www.' + s25.domain + '/#') return;
                var author = s25.get_author(response);
                direct_link.href = author.blog + article_link;
            }
          );
      } 
  );


  return direct_link;
}

s25.get_author = function (response) {
  var a = $(s25.parseHtmlResponse(response)).find('.post-detal:first .author:first a:first')[0]
  return {'blog':a.href, 'className':a.className.split(" ")[2]}
}

//order - ordered list of div IDs of blocks that will be displayed first = in passed order, remaining will be left intact at the bottom
//hide - specify list of IDs of blocks to hide
s25.reorder_blogroll = function (order, hide) {
  if(!GM_getValue('blogroll_reorder',false))
    return;

  if(typeof(order)=='undefined') order = GM_getValue('blogroll_order',s25.consts.default_blogroll.join(',')).split(',');
  if(typeof(hide)=='undefined') hide = GM_getValue('blogroll_hide', '').split(',');

  GM_setValue('blogroll_order', order.join(','));
  GM_setValue('blogroll_hide', hide.join(','));

  if(hide && hide!='')
    for(o=0; o<hide.length; o++)
      $('#' + hide[o]).hide();

  if(order && order!=''){
    var odiv = $('div#content>div.content-right')[0];

    for(o=order.length-1; o>=0; o--) {
      var block = $('#' + order[o]);
      if(!block.size()) continue;

      if($(block).attr('id') == 'my-content') 
        $(block).find('script').remove(); //javascript wczytujący licznik psuje

      $(odiv).prepend($(block));
    }
  }

}

s25.replaceFirst = function (arr, replaceTo, replaceWith) {
  for(var i=0; i<arr.length;i++ ) {  
    if(arr[i]==replaceTo)
      arr[i] = replaceWith;
      break;
  }
  return arr;
}

s25.create_draggable_blogroll = function () {
  $('.boxbody').css('background-color','white');

  $('#my-last-in-newspapers,#my-last-comments,#my-last-posts,#my-popular-posts,#my-last-discussions')
    .draggable({'handle':'h3', 'revert':'invalid', 'scroll':true, 'zIndex':'2000','cursor':'move','revertDuration':0});

  $('#my-content')
    .draggable({'handle':'.user-counter', 'revert':'invalid', 'scroll':true, 'zIndex':'2000','cursor':'move'});

  $('#my-content,#my-last-in-newspapers,#my-last-discussions,#my-last-comments,#my-last-posts,#my-popular-posts,#my-last-discussions').droppable({
    drop : function(event, ui) {
        $(this).css('border','none');
        var drag_id = ui.draggable.attr('id');
        var drop_id = $(this).attr('id')
        $(ui.draggable).css({'top':'0px','left':'0px'});
        setTimeout(function() {
          $(this).css('background-color','white');
          var order = GM_getValue('blogroll_order', s25.consts.default_blogroll.join(',')).split(',');
          for(var i=0;i<order.length;i++) {
              if(order[i]==drag_id) order[i] = drop_id;
              else if(order[i]==drop_id) order[i] = drag_id;
          }
          s25.reorder_blogroll(order, GM_getValue('blogroll_hide', '').split(','));
        }, 0);
    },
    over: function(event, ui) {
        $(this).css('border','solid 3px red');
    },
    out: function(event,ui) {
        $(this).css('border','none');
    }
  });
}

s25.get_active_discussions = function (response) {
    var ul = s25.elem('ul', {className:'post-list'});
    $('.sg-left .post-list li', s25.parseHtmlResponse(response)).each(function() {
        var author = $(this).find('.author')[0];
        if(typeof(author)=='undefined') return;

        $(ul).append(s25.elem('li', {}, [s25.elem('h3',{}, [s25.elem('a', {href:$(this).find('h3 a').attr('href'), innerHTML:$(this).find('h3 a').attr('innerHTML')})]),
                                      author]));
    });
    var div = s25.el('div', {className:'box', style:{width:'200px', position:'absolute', marginLeft:'590px'}},
                  s25.el('div', {className:'likeh3', innerHTML:'Dyskusje'}),
                  ul,
                  s25.el('div', {style:{textAlign:'right', padding:'0px 5px 5px 0px'}}, 
                      s25.el('a', {href:'/discussions/', innerHTML:'więcej&nbsp;>>'})),
                  s25.el('div', {className:'cb'})
                  );
    $('.sg-left').after(div);
}

s25.on_window_focused = function () {
  s25.update_ui();
}

s25.show_watched = function (response) {
    var watched = s25.parse_watched(s25.parseHtmlResponse(response));

    var tbl = s25.el('table', {},
                              s25.el('tr', {}, 
                                  s25.el('th', {innerHTML:'Notka'}),
                                  s25.el('th', {innerHTML:'Nowe'})));

    for(var i=0;i<watched.rows.length;i++) {
      var row = watched.rows[i];
      if(row.ncomments <= 0) continue;
      tbl.appendChild(s25.el('tr', {}, 
                                    s25.el('td', {}, s25.el('a',{href:row.link, innerHTML:row.title})),
                                    s25.el('td', {width:'25px'}, s25.el('a', {href:row.link+'#show-last-'+row.ncomments ,innerHTML:''+row.ncomments, style:{color:'red'}}))));
    }
    var div = s25.el('div',{id:'new-notes-notification', style:{position:'fixed',left:0, bottom:'15px', backgroundColor:'#f3f3f3', display:'none'}}, 
                  tbl,
                  s25.el('span', {style:{cursor:'pointer'}, innerHTML:'zamknij', click: function() {$('#new-notes-notification').remove();}}));

    $('body').append(div);
    $(div).show('slow');
}

s25.__main__ = function () {
  s25.GM_ApiBrowserCheck();
  s25.init();
  if(!s25.domain) return; //not a Salon24-type site
  if(s25.domain != 'salon24.pl') {
    GM_log('domain not supported yet');
    return; //not a Salon24-type site
  }

  s25.debug_time('START');
  s25.check_updates(false, s25.onload_version_check_notify);

  var flist = [
    "process_url",
    "get_my_info",
    "get_account_info",
    "options_page",
    "persistent_login",
    "update_filters", 
    "update_menu", 
    "update_comments", 
    "update_post", 
    "update_post_edit", 
    "update_watched_page", 
    "update_tag_page", 
    "update_footer", 
    "update_main_page", 
    "update_discussions", 
    "after_s24_init_hooks",
    ];

  var err = 0;
  for(var f=0;f<flist.length; f++) {
    if(GM_getValue('debug', 0)) {
      err = s25[flist[f]]();
      if(err) break;
    } else {

      try {
	err = s25[flist[f]]();
	if(err) break;
      } catch (ex) {
	var loc = '';
	if(ex.fileName) loc = loc + ' file: ' + ex.fileName.replace(/.*\//,'');
	if(ex.lineNumber) loc = loc + ':' + ex.lineNumber;
	if(ex.columnNumber) loc = loc + ':' + ex.columnNumber;
	GM_log('[' + s25.meta.version + '] error at "' + flist[f] + '"' + loc + ': ' + ex.message + ' url: ' + document.location.href);
	//for (e in ex) 
	//  if(e != 'location') GM_log(e + ' (' + typeof(ex[e]) + ') ' + ex[e]);
      }
    }

  }

  s25.debug_time('END');

  if(!err && GM_getValue('blogroll_reorder',false ))
    s25.waitForLibs(100); // loaded at the begining of s25.init()
}

s25.waitForLibs = function (timeout) {
    if (typeof($().draggable)=='undefined') {
        if(timeout>10000) { // for some reason sometimes it just doesn't load them no matter how long we wait.
          GM_log('giving up unable to load jquery ui');
          return;
        }
        window.setTimeout(function() {s25.waitForLibs(timeout*2);}, timeout);
    }
    else {
      GM_log('success! jquery ui loaded!');
      s25.create_draggable_blogroll();
    }
}


s25.GM_ApiBrowserCheck();
if(gvar.isBuggedChrome && typeof(window.__main__) == 'undefined') {
  GM_log('applying super hack');
  s25.super_hack();
} else {
  s25.__main__();
}
